c++ - 将模板方法移动到派生中断编译

标签 c++ inheritance overloading

给定以下代码:

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() 的正确重载版本被选择并为 aa.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/

相关文章:

go - 将结构 B(继承自结构 A) append 到结构 A 的一片中

java - 如何推断类型,其中返回类型也是方法参数的上限和下限

c++ - 好友功能无法识别

c# mvc 3, Action 重载?

java - 如何有效地使用重载和多态性

c++ - 数据传输协议(protocol)设计

java - super() 构造函数中的初始化问题

c++ - 无法将函数定义与 cpp 中的现有声明相匹配

c++ - 升压asio : Unable to read URL Body (JSON)

c++ - 数组一直只返回最后一个元素。 [C/阿杜伊诺]