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!


  • Mod

    Ganz einfach: MyPtr<Base> und MyPtr<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 von operator= 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?


Log in to reply