【问题标题】:Why can't a class method call a global function with the same name?为什么类方法不能调用同名的全局函数?
【发布时间】:2015-10-22 23:04:34
【问题描述】:

以下代码显示了一个函数调用另一个函数。
两者名称相同,但签名不同。
这按预期工作。

//declarations
void foo();
void foo(int);

int main(){
  foo();
}

//definitions
void foo(){
    foo(1);
}
void foo(int){}

我现在要做的唯一不同是将其中一个函数包装到一个结构中:

//declarations
struct Bar{
    void foo();
};
void foo(int);

int main(){
  Bar bar;
  bar.foo();
}

//definitions
void Bar::foo(){
    foo(1);
}
void foo(int){}

编译失败。

In member function ‘void Bar::foo()’:
error: no matching function for call to ‘Bar::foo(int)’
         foo(1);
              ^
note: candidate: void Bar::foo()
     void Bar::foo(){
          ^
note:   candidate expects 0 arguments, 1 provided

当全局函数存在时,我不明白为什么它要调用 foo(int) 作为方法。
它没有提及歧义,只是找不到功能。

为什么会发生这种情况,我该如何解决?

旁注:我将旧的 C 代码包装在 C++ 包装器中,并且大多数 C++ 方法都是对全局 C 函数的调用,这些函数隐式传入包装的结构。这与上面发生的情况类似(就编译器错误而言)。

【问题讨论】:

标签: c++ function methods overloading function-prototypes


【解决方案1】:

成员函数隐藏了全局。它在类上下文中找到名称,因此它不会继续在其他上下文中搜索它。

你需要这样称呼它:

::foo(1);

另一种解决方案是在函数内部使用前向声明,如下所示:

void Bar::foo()
{
    void foo(int);
    foo(1);
}

正如 Praetorian 建议的那样,这是另一种选择:

void Bar::foo()
{
    using ::foo;
    foo(1);
}

【讨论】:

  • 或在Bar::foo内添加using ::foo;
  • 在 Visual Studio 中,在没有类名的情况下添加 using 是不合法的。它给出了以下错误:“foo:symbol cannot be used in a member using-declaration”只能在它允许的函数内使用,并且像 fw 声明一样工作。
  • 什么版本的VS? This 在 VS2015 上编译。
  • 函数内部的@Praetorian 是有效的(就像前向声明一样),在它没有编译的类中,我会将您的解决方案添加到答案中......
  • 是的,不能在班级范围内这样做。在这种情况下,using 声明只能用于将基类成员带入作用域。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-22
  • 2011-11-01
  • 2012-08-30
  • 1970-01-01
  • 2015-11-17
相关资源
最近更新 更多