Suppose I have class D which inherits from class B. and I have a template class template <class T> C. And then I have a function signature void foo(C<B> c);. In order to make that work with an instance of C templated with a derived class from B do I need to provide a conversion constructor? Something like template <class DERIVED> C(const C<DERIVED>& c) {}? Will this be enough for anything else that happens in C since any D is a B?
Suppose I have class D which inherits from class B . and I have
Share
C<D>andC<B>will not be related types at all, so yes, you’d have to provide a conversion that allows aC<B>to be constructed from aC<D>.This probably will not make the types perfectly compatible. For example a function
void foo(C<B> &c)will not be able to use that conversion.Whether these unrelated types can be made compatible enough for your uses depends on how you define the types and what you need from them in terms of compatibility.
Consider this example for why there should not be any relationship between different specializations of a template:
Converting between types related by inheritance works because a derived type always has a sub-object of the base type. Even so, types that use inheritance must be carefully designed in order to work well.
User defined conversions operate via non-explicit constructors and type operators:
You can read more in the standard 12.3.2 Conversion functions [class.conv.fct] and about how they are used in overload resolution 13.3 Overload resolution [over.match].