Компилятор предпочитает выбирать конструктор шаблона с T=child
, потому что разрешение перегрузки считает, что преобразование квалификации (добавление const
к типу аргумента) лучше, чем преобразование из производного в базовое.
Итак, самый простой способ - просто объявить конструктор, принимающий в качестве аргумента дочерний элемент:
class Foo
{
public:
Foo (Parent &) {};
Foo (Child & x):Foo(static_cast<Parent&>(x)) {};
template <typename T>
Foo (const T &);
};
Обратите внимание, что если аргументом конструктора является const lvalue или rvalue, то, как и в вашем примере кода, будет выбран конструктор шаблона. Я полагаю, что это преднамеренно.