Template und const Problem
-
Hi, warum compiliert das folgende Beispiel nicht ohne die kommentierten Zeilen? Mit rohen Zeigern geht die Umwandlung eines nicht const Zeigers in einen const Zeiger ja auch.
class Base { public: Base() {}; }; template <class T> class MyPtr { public: MyPtr() {}; MyPtr(const MyPtr<T>& value) {}; /*template <class U> MyPtr(const MyPtr<U>& value) {};*/ MyPtr<T>& operator=(const MyPtr<T>& value) { return *this; }; /*template <class U> MyPtr<T>& operator=(const MyPtr<U>& value) { return *this; };*/ }; int main() { Base *obj1 = nullptr; const Base* obj2 = nullptr; obj2 = obj1; MyPtr<Base> ptr1; MyPtr<const Base> ptr2; ptr2 = ptr1; }
-
Das hat nichts mit der Pointer-Konvertierung zu tun.
Für den Compiler hat MyPtr<foo> genau so viel mit MyPtr<const foo> zu tun wie MyPtr<bar>. Das sind komplett verschiedene Klassen!
-
Ganz einfach:
MyPtr<Base>
undMyPtr<Base const>
sind zwei völlig verschiedene Typen. Du kannst sie nicht ohne weiteres ineinander konvertieren. Und genau das musst du, wenn du für das Funktionsargument vonoperator=
MyPtr<Base const>
übergibst.Du könntest auch
MyPtr& operator=(const MyPtr& value) { return *this; };
schreiben, das würde verdeutlichen dass dieser überladene Operator nur mit der jeweiligen Spezialisierung funktioniert.
-
Ok, das Problem ist, dass Construktoren anderer Klassen mit mehreren MyPtr-Argumenten, dann nicht mehr eindeutig sind, wenn ich die kommentierten Zeilen dazu nehme. Kann man das vermeiden?
-
Enumerator schrieb:
Ok, das Problem ist, dass Construktoren anderer Klassen mit mehreren MyPtr-Argumenten, dann nicht mehr eindeutig sind, wenn ich die kommentierten Zeilen dazu nehme. Kann man das vermeiden?
decltype-SFINAE-Tricks?