Reputation: 1
Is it possible to make the following work? Basically I want Ptr<B> to be an acceptable return type replacement for Ptr<A>.
template<typename T>
class Ptr {
public:
explicit Ptr (T * ptr) : ptr(ptr) {}
T * ptr;
};
class A {
virtual Ptr<A> foo () {
return Ptr<A>(NULL);
}
};
class B : public A {
virtual Ptr<B> foo () { // BAD! Ptr<B> is not compatable
return Ptr<B>(NULL);
}
};
Upvotes: 3
Views: 1345
Reputation: 1
You could try something like this:
template<class T> class Ptr
{
...
};
template<class T> class A
{
virtual Ptr<T> foo();
};
class B : public A<B>
{
virtual Ptr<B> foo();
};
Upvotes: -1
Reputation: 1993
According to the standard:
The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions. If a function D::f overrides a function B::f, the return types of the functions are covariant if they satisfy the following criteria:
So in your example the return types are not really covariant (they are not pointers nor references) and moreover Ptr<B>
and Ptr<A>
are unrelated types.
So keeping foo virtual and returning Ptr<A>
in A and Ptr<B>
in B is not possible. If you can/are willing to drop virtual than you can use something in the lines of Cem Kalyoncu's proposal or a variation of it.
Upvotes: 1
Reputation: 14603
Your can use curiously recurring templates to replace virtual function overloads with template function returns. The following article might help:
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Also check the following code:
template <class C_>
class A_Base {
Ptr<C_> foo() {
return static_cast<C_*>(this)->foo_impl();
}
}
class A : public A_Base<A> {
Ptr<A> foo_impl() { return Ptr<A>(NULL); }
}
class B : public A_Base<B> {
Ptr<B> foo_impl() { return Ptr<B>(NULL); }
}
Upvotes: 4