C++:方法重载的奇怪行为

Not*_*ist 1 c++ virtual-functions

我需要解释为什么下面的代码不能编译.我有一个解决方法,我将在下面阐述,但我不明白原始版本的失败.

加速代码读取:概念是定义一个接口(ISomething),然后创建一个抽象实现(ASomething),它(2)使用第一个(尚未定义的)实现第二个函数(1).从抽象的(例如SomethingImpl)派生的完整实现必须定义第一个方法,并具有覆盖第二个方法的选项.

#include <iostream>

class ISomething
{
public:
  virtual ~ISomething()
  { }
  virtual int f(int x) = 0; // (1)
  virtual int f(int x, int y) = 0; // (2)
};

class ASomething
  : public virtual ISomething
{
public:
  virtual int f(int x, int y) // (2)
  {
    return f(x) + f(y); // (3)
  }
};

class SomethingImpl
  : public ASomething
{
public:
  virtual int f(int x) // (1)
  {
    return x+1;
  }
};

int main()
{
  SomethingImpl a;
  std::cout << a.f(10) << std::endl; // (1)
  std::cout << a.f(10,20) << std::endl; // (2)
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译此代码会在Visual Studio 2013(Windows)和g ++ 4.4.5(Linux)上产生错误.错误非常相似,我将仅详细说明g ++输出:

$ g++     SibFun.cpp   -o SibFun
SibFun.cpp: In member function ‘virtual int ASomething::f(int, int)’:
SibFun.cpp:18: error: no matching function for call to ‘ASomething::f(int&)’
SibFun.cpp:16: note: candidates are: virtual int ASomething::f(int, int)
SibFun.cpp:18: error: no matching function for call to ‘ASomething::f(int&)’
SibFun.cpp:16: note: candidates are: virtual int ASomething::f(int, int)
SibFun.cpp: In function ‘int main()’:
SibFun.cpp:36: error: no matching function for call to ‘SomethingImpl::f(int, int)’
SibFun.cpp:26: note: candidates are: virtual int SomethingImpl::f(int)
make: *** [SibFun] Error 1
Run Code Online (Sandbox Code Playgroud)

我尝试过用不同的符号(3)一样return this->f(x) + this->f(y),但我经历了错误信息没有显著变化.

但是,当我改为我时(3),return ISomething::f(x) + ISomething::f(y);我只得到:

$ g++     SibFun.cpp   -o SibFun
SibFun.cpp: In function ‘int main()’:
SibFun.cpp:36: error: no matching function for call to ‘SomethingImpl::f(int, int)’
SibFun.cpp:26: note: candidates are: virtual int SomethingImpl::f(int)
make: *** [SibFun] Error 1
Run Code Online (Sandbox Code Playgroud)

但!当(2)从更改fg所有编译并按预期运行时.

这个乞求背后的原因是什么?为什么我不能使用这个f名字(2)

Pio*_*cki 7

函数重载仅适用于同一范围内可见的函数:

class ASomething
    : public virtual ISomething
{
public:
  virtual int f(int x, int y) // (2)
  {
    return f(x) + f(y); // (3)
  }

  using ISomething::f;
  //~~~~~~~~~~~~~~~~~^
};

class SomethingImpl
   : public ASomething
{
public:
  virtual int f(int x) // (1)
  {
    return x+1;
  }    

  using ASomething::f;
  //~~~~~~~~~~~~~~~~~^
};
Run Code Online (Sandbox Code Playgroud)