C ++模板:重载时找不到基类类型参数方法

时间:2017-08-08 16:18:05

标签: c++ templates overloading

请考虑以下示例:

#include <iostream>

class Base {
public:
  virtual void foo(std::string str) = 0;
  void foo() { foo("LOL"); }
};

class Derived : public Base {
public:
  void foo(std::string str) { std::cout << str << std::endl; }
};

template<class T> class MyTemplate {
public:
  void print() { a.foo(); }
  T a;
};

int
main(int argc, char** argv)
{
  MyTemplate<Derived> a;
  a.print();
}

编译时,我有以下错误:

main.cpp: In instantiation of ‘void MyTemplate<T>::print() [with T = Derived]’:
main.cpp:24:11:   required from here
main.cpp:16:18: error: no matching function for call to ‘Derived::foo()’
   void print() { a.foo(); }
                  ^
main.cpp:16:18: note: candidate is:
main.cpp:11:8: note: virtual void Derived::foo(std::string)
   void foo(std::string str) { std::cout << str << std::endl; }
        ^
main.cpp:11:8: note:   candidate expects 1 argument, 0 provided

它发现解决方案是写:

  void print() { a.Base::foo(); } 

但为什么呢?为什么G ++不能自己找到Base :: foo()方法呢?

由于

1 个答案:

答案 0 :(得分:1)

原因是类foo中的方法Derived隐藏了从类Base继承的所有具有相同名称的方法。因此,只有单个版本的方法foo接受std::string作为参数才能通过Derived进行调用。因此,您必须使用以下语法调用foo,它不接受任何参数:

a.Base::foo();

请注意,您还可以使用using declarationfoo类中显示继承的Derived

class Derived : public Base {
public:
  using Base::foo;
  void foo(std::string str) { std::cout << str << std::endl; }
};

通过此更改,下一个代码变为有效:

a.foo();