Reputation: 1437
Given following code:
class MyClass {};
template< class T > class Base {};
template< class T > class Derived : public Base< const T > {};
Base< const MyClass* >* MyFunc ()
{
return new Derived< MyClass* >();
}
clang gives:
error: cannot initialize return object of type 'Base<const MyClass *> *' with an rvalue of type 'Derived<MyClass *> *'
However, "Derived MyClass*" is derived from "Base const MyClass*", so I expected it to work. What did I get wrong ?
Upvotes: 0
Views: 89
Reputation: 206567
The source of confusion:
const MyClass* ptr; // ptr is is a non-const pointer to a const object
MyClass* const ptr; // ptr is a const pointer to a non-const object.
Hence, you need to use:
Base< MyClass const* >* MyFunc ()
{
return new Derived< MyClass* >();
}
Upvotes: 0
Reputation: 65600
This is because Derived<MyClass*>
is derived from Base<MyClass* const>
, not Base<const MyClass*>
. The former means a const
pointer to MyClass
, the latter means a pointer to a const MyClass
.
You need to think about what you want to be const
: the pointer or the pointee.
If it's the pointer, then just change the return type to Base<MyClass* const>
*.
If it's the pointee, then you'll need to do some transformations on T
in your definition for Derived
. If you only expect T
to be a pointer, then const std::remove_pointer_t<T>*
will probably work for you, otherwise you'll need to do some partial specialization.
Upvotes: 2
Reputation: 170055
Derived< MyClass* >
is derived from Base<MyClass * const>
.
Note what becomes const
here, since T
is not MyClass
, but MyClass*
If you want to force the const
to be applied to the pointee when T
is a pointer type, you need to make use of a helper template & some meta-programming.
Upvotes: 2