$ 7.3.3 / 14(C ++ 03)
struct A { int x(); };
struct B : A { };
struct C : A {
using A::x;
int x(int);
};
struct D : B, C {
using C::x;
int x(double);
};
int f(D* d) {
return d->x(); // ambiguous: B::x or C::x
}
'f'中代码中的注释表示可以预期'B :: x'或'C :: x'之间存在歧义。
但是,在使用g ++(ideone)或Comeau进行编译时,错误会略有不同。这些错误而不是指示B :: x或C :: x中的歧义表明A是D的模糊基数这一事实
prog.cpp:在函数'int f(D *)'中: prog.cpp:16:错误:'A'是一个 “D”的模糊基础
并且
“ComeauTest.c”,第21行:错误:基数 “A”类是含糊不清的 return d-> x(); //不明确:B :: x或C :: x
按照$ 10.2中的名称查找规则,我觉得代码片段中的注释并不正确。该错误确实首先与基类“A”的模糊性有关,而不是与其他任何事物有关(例如,重载决策中的模糊性)。有什么想法吗?
答案 0 :(得分:2)
这是由C ++ 03中的名称查找扭曲引起的:检查明确的子对象是C ++ 03中类成员名称查找的一部分。 C ++ 03中的查找将找到D :: X和C :: x以及A :: x,其中A :: x匹配,但与A类型的两个不同子对象相关联。
在C ++ 0x中,检查明确的子对象现在是相应子条款的一部分,请参阅DR #39:x
直接成为其成员的类是一个模糊的基础 - 所以子句5将导致编译错误,而不是第10条。
请注意,评论会讨论A
的子对象。 A
的一个子对象遍历路径B
,另一个A
的子对象遍历路径C
。这就是评论“B::x
或C::x
”的原因。可以通过仅尝试转换为其类类型来确定相同类类型的多个子对象的存在,忽略可访问性问题:如果转换不明确,则子对象出现多次。
答案 1 :(得分:0)
Clang ++给出了g ++和Comeau
产生的错误的组合C:\Users\SUPER USER\Desktop>clang++ chubsdad.cpp
chubsdad.cpp(12) : error: ambiguous conversion from derived class 'D' to base class
'A':
struct D -> struct B -> struct A
struct D -> struct C -> struct A
return d->x(); // ambiguous: B::x or C::x
^
1 error generated.