4

$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'的模糊基数</p>

“ComeauTest.c”,第 21 行:错误:基类“A”不明确 return d->x(); // 模棱两可:B::x 或 C::x

按照 $10.2 中的名称查找规则,我觉得代码片段中的注释并不真正正确。该错误确实首先与基类“A”的歧义有关,而不是其他任何事情(例如重载决议中的歧义)。有什么想法吗?

4

2 回答 2

2

这是由 C++03 中名称查找的一个扭曲引起的:检查明确的子对象是 C++03 中类成员名称查找的一部分。在 C++03 中查找将找到 D::X 和 C::x 和 A::x,其中 A::x 匹配,但与 A 类型的两个不同子对象相关联。

在 C++0x 中,检查明确的子对象现在是各个子条款的一部分,请参阅DR #39x直接作为其成员的类是不明确的基 - 所以第 5 条将导致编译错误,而不是子句10.

请注意,评论谈论的是A. 它的一个子对象A越过 path B,另一个子对象A越过 path C。这就是为什么评论说“B::xC::x”。同一类类型的多个子对象的存在可以通过尝试转换为其类类型来确定,忽略可访问性问题:如果转换不明确,则子对象出现多次。

于 2010-11-09T07:07:21.823 回答
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.
于 2010-11-09T04:49:31.697 回答