为什么GCC不能消除多个继承的函数(但是clang可以)? [英] Why can't GCC disambiguate multiple inherited functions (yet clang can)?
问题描述
无法使用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 ++不能消除Ea对Eb的歧义
}
代码,这使我不确定如果代码是真正有效的C ++或不。我乐观地得出结论,clang是正确的,g ++是错误的,但后来我做了一个小改动,使俚语有类似的错误:
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); //两个clang和g ++说这是不明确的
}
是使用命名函数 f
,而不是 operator()
。我不明白为什么这应该是重要的,但它确实:这个版本不能用g ++或clang编译。
我认为它与隐藏基类中的函数有关,并且GCC的错误消息似乎没有帮助,即使你使用 struct
ena :实际上,错误消息是误导的,因为现在
Ea
和 Eb
是两个不同的类,无隐式转换从 Ea
到 Eb
,不应该出现歧义,但GCC似乎不同意我的意见: http://ideone.com/cvzLW
struct Sbroken:Sa,Sb
{
使用Sa :: operator();
using Sb :: operator();
};
那么它的工作原理: http://ideone.com/LBZgC
与其他示例一样:
struct Sbroken:Sa,Sb
{
使用Sa :: f;
using Sb :: f;
};
Possible Duplicate:
Why do multiple-inherited functions with same name but different signatures not get treated as overloaded functions?
This fails to compile in the indicated place with 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
}
Clang 2.8 does compile this code, which makes me uncertain if the code is really valid C++ or not. I was about to conclude optimistically that clang was right and g++ was wrong, but then I made a small change which made clang have a similar error:
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
}
The only change I made there was to use a named function f
rather than operator()
. I don't see why this should even matter, but it does: this version does not compile with g++ nor with clang.
I think it has something to do with hiding the function(s) in the base classes, and the GCC's error message doesn't seem to help much, even if you use struct
instead of enum
: In fact, the error message is misleading, because now Ea
and Eb
are two different classes, with no implicit conversion from Ea
to Eb
, the ambiguity shouldn't arise, but GCC seems to disagree with me : http://ideone.com/cvzLW (see the modification also).
Anyway, if you bring the functions in the class scope, explicitly by writing using
as:
struct Sbroken : Sa, Sb
{
using Sa::operator();
using Sb::operator();
};
then it works : http://ideone.com/LBZgC
Same with other example as well:
struct Sbroken : Sa, Sb
{
using Sa::f;
using Sb::f;
};
Code : http://ideone.com/3hojd
这篇关于为什么GCC不能消除多个继承的函数(但是clang可以)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!