MickaëlG
MickaëlG

Reputation: 1437

template issue with class derived from const

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

Answers (3)

R Sahu
R Sahu

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

TartanLlama
TartanLlama

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

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

Related Questions