子类调用意外的重载函数



我正在努力理解为什么在下面的代码中调用了所谓的错误重载。

// overload.h
 struct T1
    {
      template<class... Args>
      void doFoo(Args&&... args)
        {
        std::cout << "T1 doFoo generic"<< std::endl;
        }
      void doFoo(int a)
        {
        std::cout << "T1 doFoo INT "<< std::endl;
        }
      void doFoo(double a)
        {
        std::cout << "T1 doFoo Double "<< std::endl;
        }
      template<class... Args>
      void foo(Args&&... args)
        {
        doFoo(args...);
        }
    };

  struct T2 : public T1
    {
      void doFoo(char c)
        {
        std::cout << "T2 doFoo char " << std::endl;
        }
    };
  // main.cpp
  #include <overload.h>
  int main()
    {
    T2 t2;
    t2.foo(3);
    t2.foo('A'); // This outputs: T1 doFoo generic 
    }

我期待t2.foo('A')作为输出:"T2 doFoo char",但相反,我得到了"T1 doFoo泛型"。

如果我将 T2::d oFoo(char c( 移动到 T1 中,一切都按预期工作。这种行为的原因是什么?有什么解决方法吗?

正如注释中已经建议的那样,由于T1不知道派生的结构T2T1::foo也找不到T2::doFoo(char c)并且无法实现此静态绑定。

T2中为char虚假重载T1::foo的简单解决方法是再次在T2中声明foo并重载它,如下所示:

演示

struct T1 
{
    template<class... Args>
    void doFoo(Args&&... args){
        std::cout << "T1 doFoo generic"<< std::endl;
    }
    void doFoo(int a){
        std::cout << "T1 doFoo INT "<< std::endl;    
    }
    void doFoo(double a){
        std::cout << "T1 doFoo Double "<< std::endl;
    }
    template<class... Args>
    void foo(Args&&... args){
        doFoo(std::forward<Args>(args)...);
    }
};
struct T2 : public T1
{
    template<class... Args>
    void foo(Args&&... args){
        T1::foo(std::forward<Args>(args)...);
    }
    void foo(char c){
        std::cout << "T2 foo char " << std::endl;
    }
};

最新更新