名称查找中的重载分辨率/歧义(哪一个) [英] Overload Resolution/Ambiguity in name lookup(which one)

查看:97
本文介绍了名称查找中的重载分辨率/歧义(哪一个)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

$ 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"是模棱两可的 返回d-> x();//不明确:B :: x或C :: x

按照$ 10.2中的名称查找规则,我感到代码片段中的注释不是真正正确的.该错误确实首先与基类'A'的歧义有关,而不是与其他任何东西有关(例如,过载解析中的歧义).有什么想法吗?

解决方案

这是由于C ++ 03中名称查找的错误所致:检查无歧义的子对象是C ++ 03中类成员名称查找的一部分.在C ++ 03中,查找将找到D :: X和C :: x以及A :: x,其中A :: x匹配,但与两个类型为A的不同子对象相关联.

在C ++ 0x中,检查明确的子对象现在是相应子条款的一部分,请参见B::x或C::x"的原因.可以通过尝试转换为其类类型,而忽略可访问性问题来确定是否存在相同类类型的多个子对象:如果转换不明确,则子对象会出现多次.

$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
}

The comment in the code in 'f' indicates that one can expect ambiguity between 'B::x' or 'C::x'.

However, on compiling with g++(ideone) or Comeau the errors are slightly different. These errors instead of indicating ambiguity in B::x or C::x indicate the fact that A is an ambiguous base of D

prog.cpp: In function ‘int f(D*)’: prog.cpp:16: error: ‘A’ is an ambiguous base of ‘D’

And

"ComeauTest.c", line 21: error: base class "A" is ambiguous return d->x(); // ambiguous: B::x or C::x

Going by the name lookup rules in $10.2, I get a feel that the comment in the code snippet is not really correct. The error is indeed first and foremost related to ambiguity of base class 'A' rather than anything else (e.g. ambiguity in overload resolution). Any thoughts?

解决方案

This is caused by a twist in name-lookup in C++03: Checking for an unambiguous subobject was part of class member name lookup in C++03. Lookup in C++03 will find D::X and C::x and A::x, where A::x matches, but is associated with two distinct subobjects of type A.

In C++0x, the checking for an unambiguous subobject is now part of the respective subclauses, see DR #39: The class where x is directly a member of is an ambiguous base - so clause 5 will cause a compile error, instead of clause 10.

Note that the comment talks about the subobjects of A. There is one subobject of A that goes over path B, and another subobject of A that goes over path C. This is why the comment says "B::x or C::x". The presence of multiple subobjects of the same class type can be determined by just trying to convert to its class type, ignoring accessibility issues: If the conversion is ambiguous, the subobject appeared multiple times.

这篇关于名称查找中的重载分辨率/歧义(哪一个)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆