【问题标题】:Ambiguous call to overloaded static function对重载静态函数的模糊调用
【发布时间】:2012-02-25 23:10:47
【问题描述】:

我对这种情况感到困惑,谷歌搜索并没有给我答案。基本上我有以下无法编译的简单代码:

#include <iostream>

class A
{
public:
    int a(int c = 0) { return 1; }
    static int a() { return 2; }
};

int main()
{
    std::cout << A::a() << std::endl;
    return 0;
}

在编译此代码时,GCC 4.2 表示在 main() 中对 A::a() 的调用与 a() 有效候选者的两个版本都模棱两可。 Apple 的 LLVM 编译器 3.0 编译没有错误。

为什么 gcc 对我要调用哪个函数感到困惑?我认为很明显,通过将a()A:: 匹配,我要求的是函数的static 版本。当然,如果我删除了static 函数a(),这段代码仍然无法编译,因为A::a() 不是调用非static a() 的有效语法。

感谢您的任何评论!

【问题讨论】:

  • 顺便说一句,我在谷歌上快速搜索:“静态和非静态成员函数 C++ 的名称解析”提出了另一个 SO 问题:stackoverflow.com/questions/5365689/…
  • 哎呀,我的 google-fu 让我失望了……

标签: c++


【解决方案1】:

这样做的原因是因为 C++ 指定这是模棱两可的。重载决议指定对于A::a,由于this 不在范围内,该调用中的参数列表由人为的A 对象参数 扩充,而不是*this。重载解析不排除非静态成员函数,而是

如果参数列表由一个人为的对象扩充,并且重载决策选择了 T 的非静态成员函数之一,则该调用是格式错误的。

这最近在core issue 1005 的背景下成为委员会广泛讨论的主题。请参阅 core issue 364 考虑更改此规则但没有这样做。

【讨论】:

  • 感谢您的参考。但是我仍然很难理解,为什么“重载解析选择 T 的非静态成员函数之一”。如果我理解您所说的正确,非静态 a() 有两个参数:this 和具有默认值 (c = 0) 的参数。静态 a() 有一个“人为的 A 对象参数”。因为我没有在调用中提供“this”指针,为什么会选择非静态版本?
  • 不,this 不是此调用中的参数,因为范围内没有 this。这就是我们在调用中传递“人为的 A 对象参数”的原因。这两个函数都有一个隐式对象参数(对于静态函数,该参数仅用于接收人为的 A 对象参数)。在您的情况下,非静态 a 的隐式对象参数的类型为 A&amp;(在 const 成员 fncs 中为 A const&amp;)。调用 A::a() 中的人为对象参数匹配两个隐式对象参数,因此您有歧义。
  • 所以这个“人为的对象参数”和 *this 是同一类型?
  • @fang 参见 13.3.1.1.1p3 和 13.3.1 的规范
  • 谢谢。我想我现在看到了。
【解决方案2】:

原因是名称解析发生在编译器执行其他任何操作之前,例如确定要使用哪个重载函数。

A:: 限定函数只是告诉编译器“查看A 的内部以找到名称a”。它实际上并不能帮助解决您所指的功能。

编辑

因此,当您键入A::a() 时,首先编译器会认为“在A 中查找可以使用operator() 的成员函数或成员”。

然后编译器会想,“好吧,这里有两种可能性,指的是哪一种?a()a(int c = 0),默认为 c=0。不确定。

如果去掉static关键字,调用obj.a()这样的函数,还是会有歧义的。

WRT LLVM 的解析器

我会说它为您做了一些额外的工作,这是标准不需要的,即假设 A::a() 是静态的。

【讨论】:

  • 有人可以回答我吗,这是否意味着对于 static 函数,static 定义构成名称修饰的一部分,用于解析目的?
  • 我不知道。但是名称修改是一个链接器问题,而不是编译器问题。
  • 了解为什么 Apple 的 LLVM 编译得很好?这是否意味着 LLVM 的解析器以其他顺序进行名称解析?
  • @fang 你用的是什么编译器?
  • @Bingo i686-apple-darwin11-llvm-g++-4.2 是抱怨歧义的人。我试过 g++-mp-4.7 还是一样的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2011-12-12
  • 2014-09-05
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多