Мне это интересно. Предположим, что у меня есть:
class Base
{
public:
template<typename T>
void foo(T& varT)
{
//
}
template<typename T, typename U>
void foo(T& varT, U& varU)
{
//
}
};
class Child : public Base
{
public:
template<typename T, typename U, typename Z>
void foo(T& varT, U& varU, Z& varZ)
{
//
}
};
Теперь, когда я пробую это:
Child c;
char cVar;
int iVar;
float fVar;
c.foo(cVar);
c.foo<int>(cVar);
c.template foo<int>(cVar);
Ни один из вызовов не работает. Они всегда затенены ошибкой "Нет соответствующей функции-члена для вызова". Может ли кто-нибудь указать мне способ решить это? Я прочитал в стандарте, что унаследованные функции теневого шаблона объектов, но стандарт явно сказал, что список параметров должен быть таким же, если они затенены.
Цените помощь.
Скрытие базовых элементов всегда происходит, когда у вас есть имя в производном классе, которое присутствует в базовом классе. Основная причина заключается в том, что желательно защищать использование производного класса от изменений в базовом классе: при условии, что имена из баз не были скрыты, если добавлена новая перегрузка в базовом классе, рабочий захват с производным членом может быть захвачен чтобы скорее ссылаться на базовый класс без указания в производном классе, что что-то может произойти в базовом классе. Если вы хотите сделать доступными базовые элементы, вы можете использовать декларацию using
:
class Child : public Base
{
public:
using Base::foo; // declare that you want look up members from the base class
template<typename T, typename U, typename Z>
void foo(T& varT, U& varU, Z& varZ)
{
//
}
};
В вашем коде у вас было три вызова:
c.foo(cVar)
работает с объявлением using
.c.foo<int>(cVar)
не работает даже с объявлением using
потому что вы не можете привязать ссылку non- const
к int
к значению char
lvalue. Использование c.foo<char>(cVar)
будет работать.c.template foo<int>(cVar)
страдает от одной и той же проблемы. Поскольку c
явно не является зависимым именем, нет необходимости использовать template
в этом контексте. Без объявления using
вы можете вызвать участника, явно указав вызов, например:
c.Base::foo(cVar);
Вам нужно это: http://en.cppreference.com/w/cpp/language/using_declaration
Добавить в определение Child:
using Base::foo;