Учитывая следующий код:
template<typename T>
class A
{
public:
T t;
};
class B
{
public:
void foo(int i) {}
template<typename T>
void foo(A<T>& a) {}
};
int main()
{
A<int> a;
B b;
b.foo(a );
b.foo(a.t);
}
Это компилируется и работает нормально; правильные перегруженные версии B::foo()
выбраны и призваны a
а также a.t
,
Теперь я представляю новый класс C
который вытекает из B
и переместить шаблон версии ::foo()
снаружи B
и в C
:
template<typename T>
class A
{
public:
T t;
};
class B
{
public:
void foo(int i) {}
};
class C: public B
{
public:
template<typename T>
void foo(A<T>& a) {}
};
int main()
{
A<int> a;
C c;
c.foo(a ); // Fine
c.foo(a.t); // Error
}
И теперь код больше не будет компилироваться. Visual Studio 2005 заявляет:
error C2784: 'void C::foo(A<T> &)' : could not deduce template argument for 'A<T> &' from 'int'
На самом деле, зовет C::foo()
с любым int
значение приводит к этой ошибке. Это почти похоже на перегрузку метода для int
скрыт перегрузкой шаблона.
Почему это происходит? Это какая-то проблема с компилятором Visual Studio 2005? К сожалению, я не могу проверить это на любом другом компиляторе прямо сейчас.
Любая информация приветствуется.
Похоже, перегрузка метода для int скрыта перегрузкой шаблона.
Именно так! Вам нужно добавить объявление использования в класс C:
class C: public B
{
public:
using B::foo;
template<typename T>
void foo(A<T>& a) {}
};
Когда вы объявляете функцию-член в производном классе, все функции-члены в базовом классе с одинаковым именем скрываются. См. §3.3.10 / 3 ИСО / МЭК 14882: 2011:
Объявление члена в производном классе (раздел 10) скрывает объявление члена базового класса с тем же именем; см. 10.2.
Он прячется, никаких перегрузок. использование
class C: public B
{
public:
using B::foo;
template<typename T>
void foo(A<T>& a) {}
};
Правильно, базовая функция скрытый. Это на самом деле правильный термин для этого. добавлять using B::foo;
к определению класса C
чтобы показать это.