简体   繁体   English

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

[英]Ambiguous call to overloaded static function

I'm confused by this situation and googling didn't give me the answer. 我对这种情况很困惑,谷歌搜索没有给我答案。 Basically I have the following simple code that doesn't compile: 基本上我有以下不编译的简单代码:

#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;
}

In compiling this, GCC 4.2 says the call to A::a() in main() is ambiguous with both versions of a() valid candidates. 在编译时,GCC 4.2表示对main() A::a()的调用与a()有效候选的两个版本都不明确。 Apple's LLVM compiler 3.0 compiles with no error. Apple的LLVM编译器3.0编译时没有错误。

Why is gcc confused about which function I want to call? 为什么gcc对我要调用哪个函数感到困惑? I thought it was obvious that by qualifying a() with A:: I'm asking for the static version of the function. 我认为很明显,通过用A::限定a()我要求函数的static版本。 Naturally this code still doesn't compile if I remove the static function a() , because A::a() is not valid syntax for calling the non- static a() . 当然,如果我删除static函数a() ,这段代码仍然无法编译,因为A::a()不是调用非static a()有效语法。

Thanks for any comment! 谢谢你的评论!

The reason for this is because C++ specifies that this is ambiguous. 原因是因为C ++指定这是不明确的。 Overload resolution specifies that for A::a , since this is not in scope, the argument list in that call is augmented by a contrived A object argument , instead of *this . 重载决策指定对于A::a ,因为this不在范围内,该调用中的参数列表由设计的A对象参数增强,而不是*this Overload resolution does not exclude non-static member functions, but instead 重载决策不排除非静态成员函数,而是排除

If the argument list is augmented by a contrived object and overload resolution selects one of the non-static member functions of T, the call is ill-formed. 如果参数列表由设计对象增强并且重载决策选择T的非静态成员函数之一,则调用是错误的。

This has recently been subject of extensive discussion both in the committee in context of core issue 1005 . 最近,在核心问题1005的背景下,委员会对此进行了广泛讨论。 See core issue 364 which considered changing this rule but didn't do so. 请参阅核心问题364 ,该问题考虑更改此规则但未执行此操作。

The reason is name resolution happens before anything else the compiler does, like figuring out which overloaded function to use. 原因是名称解析在编译器执行任何其他操作之前发生,例如找出要使用的重载函数。

Qualifying the function with A:: simply tells the compiler to "look inside of A to find the name a ". 与修饰函数A::只是告诉编译器“看里面A找到的名字a ”。 It doesn't actually help resolve which function you are referring to. 它实际上并没有帮助您解决您所指的功能。

EDIT 编辑

And so when you type A::a() , first the compiler thinks "look in A for a member function or member who can use operator() ". 因此,当您键入A::a() ,首先编译器会认为“在A查找成员函数或可以使用operator()成员”。

Then the compiler thinks, "Ok, two possibilities here, which one is being referred to? a() or a(int c = 0) with a default c=0 . Not sure. 然后编译器认为,“好吧,这里有两个可能性,一个被引用? a()a(int c = 0) ,默认c=0不确定。

If you removed the static keyword and called the functions like obj.a() , there would still be an ambiguity. 如果你删除了static关键字并调用了像obj.a()这样的函数,那么仍然会有歧义。

WRT LLVM's parser WRT LLVM的解析器

I would say that it does some extra work for you, which is not required by the standard, which would be to assume A::a() is static. 我会说它为你做了一些额外的工作,这不是标准所要求的,假设A::a()是静态的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM