Operatoren/Overloading/Templates
-
Ich sitze hier gerade vor einem ziemlich eigenartigen Problem. Nehmen wir an ich habe folgenden Code:
template<typename A> class Foo { public: // operator A(); }; template<typename A, typename B> static A Bar(B Value); template<typename A, typename B> static A Bar(Foo<B> Value);Wie man hier sieht, hat Foo<A> einen Operatoren zur impliziten Konvertierung nach A. Die Funktion Bar<A, B> soll im Fall, dass sie zusammen mit einem Object Foo<B> anstelle eines Objektes B aufgerufen wird, anderen Code ausführen. Das Problem besteht darin, dass der Compiler nicht weiss, welche Funktion er aufrufen will. Der Quelltext zur Klasse Foo<A> darf aber nicht geändert werden. Gibt es dafür eine Lösung?
-
Mir fällt eine recht hässliche Lösung ein:
Man erstelle sich eine simple zusätzliche Templateklasse:
template <class T> class Funny { T my_intern; Funny<T>& operator=(const Funny<T>&); //op== verbergen Funny<T>(const Funny<T>&); //copy-ctor verbergen public: explicit Funny(T& arg) : my_intern(arg) {}; //macht aus einem T ein Funny<T> ~Funny() {}; operator T() { return my_intern; } //macht aus dem funny wieder ein T } template<typename A, typename B> static A InnerBar(B Value); template<typename A, typename B> static A InnerBar(Foo<B> Value); template<typename A, typename B> static A Bar(Funny<B> Value) { return InnerBar(Value); }Auzurufen ist jetzt nur Bar. Das besondere: wenn du Bar mit Foo<X> aufrufst, dann wird erst ein Funny< Foo<X> > erstellt, und zwar Implizit. Es wird auf jedenfall kein Funny<X> erstellt, weil der Compiler nicht zwei implizite Typumwandlungen auf einmal macht, und das müsste er:
Foo<X> --> X --> Funny<X>Wenn dann InnerBar aufgerufen wird, wird aus dem Funny ein Foo gemacht, aber nicht Funny -> Foo -> B, weils wieder zwei konvertierungen wären.
Bin allerdings nicht ganz sicher ob das tut...
Edit: alles blödsinn..
Nein, dein Problem kann man nicht lösen, weil das B aus dem ersten Template ja genausogut ein Foo<X> sein könnte. stell dir mal vor, was passieren soll, wenn jemand Bar(Foo< Foo< Foo<X> > >) aufruft... dann ist eben B = Foo< Foo< Foo<X> > >
-
template<typename A, typename B> static A Bar(Foo<B> Value);wenn ich das richtig sehe, kann die funktion ohnehin nur qualifiert aufgerufen werden, denn A kann der compiler nicht aus dem aufruf herleiten. eine spezialisierung für Foo<B> fällt ebenfalls aus, denn partielle spezialisierungen sind für funktionen nicht möglich.