对重载静态函数的模糊调用

时间:2012-02-25 23:10:47

标签: c++

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

#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表示A::a()中对main()的调用对a()个有效候选版本的两个版本都不明确。 Apple的LLVM编译器3.0编译时没有错误。

为什么gcc对我要调用哪个函数感到困惑?我认为显而易见的是,通过a()A::进行限定,我要求static版本的功能。当然,如果删除static函数a(),此代码仍然无法编译,因为A::a()不是调用非static a()的有效语法。

感谢您的任何评论!

2 个答案:

答案 0 :(得分:6)

原因是因为C ++指定这是不明确的。重载决策指定对于A::a,由于this不在范围内,该调用中的参数列表由设计的A对象参数而不是{{1}增强}。重载决策不排除非静态成员函数,而是

  

如果参数列表被设计对象增强,并且重载决策选择了T的非静态成员函数之一,则调用格式不正确。

这最近在委员会的core issue 1005背景下进行了广泛的讨论。请参阅考虑更改此规则的core issue 364但未执行此操作。

答案 1 :(得分:3)

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

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

修改

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

然后编译器认为,“好的,这里有两种可能性,哪一个被引用?a()a(int c = 0),默认为c=0。不确定。

如果您删除了static关键字并调用了obj.a()这样的函数,那么仍会存在歧义。

WRT LLVM的解析器

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