以下程序被gcc拒绝为含糊不清的:
struct Aint { virtual void foo(int); }; struct Astring { virtual void foo(std::string); }; struct A: public Aint, public Astring {}; int main() { std::string s; A a; a.foo(s); return 0; } > vt.cpp: In function ‘int main()’: vt.cpp:13:9: error: request for > member ‘foo’ is ambiguous > a.foo(s); > ^ vt.cpp:5:34: note: candidates are: virtual void Astring::foo(std::__cxx11::string) > struct Astring {virtual void foo(std::string);}; > ^ vt.cpp:4:31: note: virtual void Aint::foo(int) > struct Aint {virtual void foo(int);};
由于同样的原因,Clang一直拒绝该计划:
clang -std=c++1y -c vt.cpp vt.cpp:13:9: error: member 'foo' found in multiple base classes of different types a.foo(s); ^ vt.cpp:4:31: note: member found by ambiguous name lookup struct Aint {virtual void foo(int);}; ^ vt.cpp:5:34: note: member found by ambiguous name lookup struct Astring {virtual void foo(std::string);};
我不完全确定我是否正确理解了第10.2节中的查找规则,因此我将按照以下步骤中的规则来计算查找集S(foo,A):
1. A does not contain `foo`, so rule 5 applies and S(foo, A) is initially empty. We need to calculate the lookup sets S(foo, Aint) and S(foo, Afloat) and merge them to S(foo, A) = {} 2. S(foo, Aint) = {Aint::foo} 3. S(foo, Afloat) = {Afloat::foo} 4. Merge S(foo, Aint) = {Aint::foo} into S(foo, A) = {} to get S(foo, A) = {Aint::foo} (second case of 6.1) 5. Merge S(foo, Afloat) = {Afloat::foo} into {Aint::foo}. This create an ambiguous lookup set because of rule 6.2
结果集是无效集,因此程序格式错误.
我想知道为什么这么早就被拒绝了.在这种情况下,编译器应该很容易进行重载解析,因为两个函数具有相同的名称但签名不同,因此没有真正的歧义.是否存在技术原因导致未执行此操作,或者是否存在其他可接受错误程序的原因?是否有人知道这么早就拒绝这些计划的决定背后的理性?