class Parent {};
class Child : public Parent {};
class Foo
{
public:
Foo (Parent &) {};
template <typename T>
Foo (const T &);
};
int main ()
{
Child c;
Foo foo (c);
}
This produces a linker error since the constructor for foo
chooses template<typename T>Foo::Foo(const T &)
instead of Foo::Foo(Parent&)
.
If c
has type Parent
instead of Child
, this uses the non-template constructor and links with no issues.
I can work around this with
Foo foo ((Parent&) c);
but I don't want to do that.
Why does C++ prefer to use a template instead of implicitly casting c
to Parent&
?
Can I change the class to prefer casting to templating, so the workaround is not needed?
The compiler prefers to choose the template constructor with
T=child
because overload resolution considers that a qualification conversion (addingconst
to the argument type) is better than a derived to base conversion.So the simplest way is just to declare a constructor taking a child as argument:
Notice that if the argument to the constructor is a const lvalue or an rvalue, then as in your example code the template constructor will be selected. I suppose that this is intentional.