将模板方法移动到微分中断编译

时间:2012-09-24 16:05:45

标签: 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'

事实上,使用任何C::foo()值调用int会导致此错误。似乎int的方法重载似乎被模板重载隐藏了。

为什么会这样?这是Visual Studio 2005编译器的一些问题吗?不幸的是,我现在无法在任何其他编译器上测试它。

感谢任何信息。

3 个答案:

答案 0 :(得分:5)

  

似乎模拟重载隐藏了int的方法重载。

完全!您需要向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:

  

派生类(第10条)中成员的声明隐藏了同名基类成员的声明;见10.2。

答案 1 :(得分:2)

它隐藏着,没有超载。使用

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

答案 2 :(得分:1)

正确,基本功能隐藏。这实际上是适当的术语。将using B::foo;添加到C的班级定义中以取消隐藏。