给定以下代码:
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'
事实上,使用任何 int
值调用 C::foo()
都会导致此错误。似乎 int
的方法重载被模板重载隐藏了。
为什么会这样? Visual Studio 2005 的编译器有问题吗?不幸的是,我现在无法在任何其他编译器上测试它。
如有任何信息,我们将不胜感激。
最佳答案
It almost seems like the method overload for int is being hidden by the template overload.
没错!您需要向 C 类添加一个 using 声明:
class C: public B
{
public:
using B::foo;
template<typename T>
void foo(A<T>& a) {}
};
当你在派生类中声明一个成员函数时,基类中同名的所有成员函数都被隐藏。参见 ISO/IEC 14882:2011 的 §3.3.10/3:
The declaration of a member in a derived class (Clause 10) hides the declaration of a member of a base class of the same name; see 10.2.
关于c++ - 将模板方法移动到派生中断编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12568776/