对重载静态函数的调用不明确

Ambiguous call to overloaded static function

本文关键字:调用 不明确 静态函数 重载      更新时间:2023-10-16

我被这种情况弄糊涂了,谷歌搜索并没有给我答案。基本上,我有以下不编译的简单代码:

#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()的两个版本都是有效的候选者。苹果的LLVM编译器3.0编译无错误。

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

感谢您的评论!

这是因为C++指定这是不明确的。重载解析指定,对于A::a,由于this不在作用域中,该调用中的参数列表由设计的a对象参数而不是*this扩充。过载解析不排除非静态成员函数,而是

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

最近,委员会在核心问题1005的背景下对这一问题进行了广泛讨论。请参阅核心问题364,该问题曾考虑更改此规则,但没有这样做。

原因是名称解析先于编译器执行任何其他操作,比如确定要使用哪个重载函数。

A::限定函数只是简单地"告诉"编译器"查看A内部以找到名称a"。它实际上无助于解决您所指的函数

编辑

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

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

如果删除static关键字并调用obj.a()之类的函数,仍然会有歧义。

WRT LLVM的解析器

我想说,它为您做了一些额外的工作,这不是标准所要求的,也就是假设A::a()是静态的。