无法在模板参数中编译非重载函数

Fail to compile non-overloaded function in template argument

我有这四个 classes :

class  BaseWrapper {
public:
  virtual void Process(int i) = 0;
};

template<typename T>
class Wrapper : public BaseWrapper {
public :
  Wrapper(T * arg): var(arg) {}
  void Process(int i) {
     this->var->Process(i);
  }
private:
  T * var;
};

class Base {
public :
  void Process(int) {}
};

class Derived : public Base {
public:
  Derived() {
    BaseWrapper * wrap = new Wrapper<Derived>(this);
  }
  void       Process(std::string) {}
};

所以基本上 Derived class 不会重载 Process 方法,而包装器需要此方法。当我编译这个时,我得到 'no matching function for call to Derived::Process(int)'.

Process 方法不应该仍然定义在 Derived class 中吗?我也试过在 Base virtual 中声明 Process 方法,它没有改变任何东西。

我不是在寻找解决方法(我通过重载 Process 方法并在其中调用父方法找到了解决方法),但我想了解为什么它无法编译。

[编辑]:如果我从 Derived 中删除 'void Process(std::string)',它会编译。因此,问题似乎来自同名的不同方法。

如果你改变这个:

void  Process(std::string) {}

对此:

void  Process(int) {}

您的代码将会编译。这是关于为什么我的代码无法编译的 strong 提示。


让我们看看这里发生了什么:

我们有:

Derived() {
  BaseWrapper * wrap = new Wrapper<Derived>(this);
}

将调用 Wrapper 的构造函数并分配数据成员 Wrapper class 与 Derived class (数据成员是一个指针,但这不是什么大问题。

现在,在 Wrapper class 中,我们有:

void Process(int i) {
  this->var->Process(i);
}

这是问题所在。你看,在这个函数体中,我们说取 Wrapper 的数据成员,它指向 class Derived 并调用 class 的 Process()我们指的是!那是 Derived class,它有 void Process(std::string),因此我们收到这个错误:

error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
      this->var->Process(i);

这与您收到的错误类似。

希望这对您有所帮助! //+1 是我今天的一个很好的入门问题:)


如果你不想重载函数,那么帮助编译器说它应该检查从基础 class 继承的方法,而不是 Derived 中定义的方法 class,应该是编译器的首选。

那么你的代码应该是这样的:

class Base; // forward declaration, or just define Base class here

template<typename T>
class Wrapper : public BaseWrapper {
public :
  Wrapper(T * arg): var(arg) {}
  void Process(int i) {
     this->var->Base::Process(i); // Say that you want the Process() of Base
  }
private:
  T * var;
};