为什么GCC不能消除多个继承函数的歧义(但是clang可以)?

Joh*_*nck 12 c++ overloading operator-overloading multiple-inheritance ambiguous

可能重复:
为什么具有相同名称但签名不同的多重继承函数不会被视为重载函数?

这无法使用g ++ 4.6.1在指定的位置进行编译:

enum Ea { Ea0 };
enum Eb { Eb0 };

struct Sa { void operator()(Ea) {} };
struct Sb { void operator()(Eb) {} };
struct Sbroken : Sa, Sb {};

struct Sworks {
    void operator()(Ea) {}
    void operator()(Eb) {}
};

int main() {
    Sworks()(Ea0);
    Sbroken()(Ea0); // g++ can't disambiguate Ea vs. Eb
}
Run Code Online (Sandbox Code Playgroud)

Clang 2.8确实编译了这段代码,这让我不确定代码是否真的有效C++.我乐观地总结出clang是对的并且g ++是错误的,但后来我做了一个小改动,使得clang有类似的错误:

enum Ea { Ea0 };
enum Eb { Eb0 };

struct Sa { void f(Ea) {} };
struct Sb { void f(Eb) {} };
struct Sbroken : Sa, Sb {};

struct Sworks {
    void f(Ea) {}
    void f(Eb) {}
};

int main() {
    Sworks().f(Ea0);
    Sbroken().f(Ea0); // both clang and g++ say this is ambiguous
}
Run Code Online (Sandbox Code Playgroud)

我在那里做的唯一改变是使用命名函数f而不是operator().我不明白为什么这应该重要,但确实如此:这个版本不用g ++和clang编译.

Naw*_*waz 5

我认为它与隐藏基类中的函数有关,并且GCC的错误消息似乎没有多大帮助,即使您使用struct而不是enum:实际上,错误消息具有误导性,因为现在EaEb是两个不同的类,有没有隐式转换EaEb,模糊不应该出现的,但GCC似乎与我不同意:http://ideone.com/cvzLW (见的修改也).

无论如何,如果你把功能类范围,明确地using为:

struct Sbroken : Sa, Sb 
{
   using Sa::operator();
   using Sb::operator();
};
Run Code Online (Sandbox Code Playgroud)

然后它工作:http://ideone.com/LBZgC

与其他示例相同:

struct Sbroken : Sa, Sb 
{
   using Sa::f;
   using Sb::f;
};
Run Code Online (Sandbox Code Playgroud)

代码:http://ideone.com/3hojd