Перемещение шаблона в компиляцию производных разрывов

Учитывая следующий код:

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? К сожалению, я не могу проверить это на любом другом компиляторе прямо сейчас.

Любая информация приветствуется.

5

Решение

Похоже, перегрузка метода для 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.

5

Другие решения

Он прячется, никаких перегрузок. использование

class C: public B
{
public:
using B::foo;
template<typename T>
void foo(A<T>& a) {}
};
2

Правильно, базовая функция скрытый. Это на самом деле правильный термин для этого. добавлять using B::foo; к определению класса C чтобы показать это.

1
По вопросам рекламы [email protected]