我对标准10.2 / 13非常困惑,
[注意:即使名称查找的结果是明确的,使用在多个子对象中找到的名称可能仍然不明确(4.11,5.2.5,5.3.1,11.2).- end note] [示例:< / p>
struct B1 {
void f();
static void f(int);
int i;
};
struct B2 {
void f(double);
};
struct I1: B1 { };
struct I2: B1 { };
struct D: I1, I2, B2 {
using B1::f;
using B2::f;
void g() {
f(); // Ambiguous conversion of this
f(0); // Unambiguous (static)
f(0.0); // Unambiguous (only one B2)
int B1::* mpB1 = &D::i; // Unambiguous
int D::* mpD = &D::i; // Ambiguous conversion
}
};
我不明白为什么这是明确的int B1 :: * mpB1 =&amp; D :: i; //明确无误
Visual C ++,Gcc和CLang都说这是对D :: i的模糊访问!
措辞似乎与核心问题#39有关 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#39,最终提案在此处:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1626.pdf
我现在发现新的基于算法的措辞(10.2 / 3-10.2 / 6)更令人困惑,因为10.2 / 9,10.2 / 10,10.2 / 11和10.2 / 13中的注释都没有完全符合至10.2 / 3-10.2 / 6。我可以将10.2 / 9-10.2 / 11作为例外,但我对10.2 / 13特别困惑。我不知道10.2 / 13的意图。
如何根据10.2 / 3-10.2 / 6查找10.2 / 13中的示例? 10.2 / 13的意图是什么,即10.2 / 13被视为10.2 / 3-10.2 / 6例外的情况是什么?
请给我一些提示。非常感谢你。
经过一番思考,我认为10.2 / 13的意图对我来说更清楚。
int B1 :: * mpB1 =&amp; D :: i; //明确无误
这应该是明确的,目前的编译器在这方面是错误的。这是明确的,因为指向类成员初始化的指针不涉及访问对象。
int D :: * mpD =&amp; D :: i; //不明确的转换
这实际上意味着当从int B1 :: * mpB1转换为int D :: * mpD时,由于基类不明确,转换是不明确的。
答案 0 :(得分:4)
对于B1 :: *情况,解释是明确的,只是从B1的开始到i的偏移。
在5.3.1 / 3中:
struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*
所以诀窍是让&amp; D :: i首先成为B1 :: *类型。然后:
int B1::* mpB1 = &D::i; // Unambiguous
很简单。然后兴趣出现:
int D::* mpD = &D::i; // Ambiguous conversion
这里RHS是B1 :: *类型,需要转换,因为我们需要确定引用哪个基数。
答案 1 :(得分:2)
此:
int B1::* mpB1 = &D::i; // Unambiguous
是明确的,因为结果被分配给了班级的pointer to member
因此,选择哪个i
并不重要,因为偏移量是相对于B成员(而不是父D类)。
所以这对你我来说是明确的,但我不认为编译器可以处理它。
答案 2 :(得分:0)
快速检查ISO IEC 14882 2003第10节没有这个例子或类似的东西。 C ++ 0x是 draft 标准,VC ++ / GCC / CLang不符合它。
我的猜测:这是新auto
打字的副产品,在较旧的C ++标准中找不到。
答案 3 :(得分:0)
FWIW,我正在复制我给这个问题的usenet副本的答案:
大家好,
我对标准的n3225 10.2 / 13非常困惑,
[注意:即使名称查找的结果是明确的,使用a 在多个子对象中找到的名称可能仍然不明确(4.11, 5.2.5,5.3.1,11.2).- end note] [示例:
struct B1 {
void f();
static void f(int);
int i;
};
struct B2 {
void f(double);
};
struct I1: B1 { };
struct I2: B1 { };
struct D: I1, I2, B2 {
using B1::f;
using B2::f;
void g() {
f(); // Ambiguous conversion of this
f(0); // Unambiguous (static)
f(0.0); // Unambiguous (only one B2)
int B1::* mpB1 = &D::i; // Unambiguous
int D::* mpD = &D::i; // Ambiguous conversion
}
};
我不明白为什么这是明确的int B1 :: * mpB1 =&amp; D :: i; // 明确的
&D::i
的类型为int B1::*
,并且明确指的是数据成员i
B1
。如果您使用D
对象取消引用它,或者将其分配给int
D::*
,则会根据需要产生歧义。
Visual C ++,Gcc和CLang都说它是对D :: i的模糊访问!
这些编译器都没有实现10.2。
措辞似乎与核心问题#39有关 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#39,和 最终提案在这里: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1626.pdf 我现在发现新的基于算法的措辞(10.2 / 3-10.2 / 6)是 更令人困惑的是因为10.2 / 9,10.2 / 10中的注释都没有, 10.2 / 11和10.2 / 13完全符合10.2 / 3-10.2 / 6。我可以做 10.2 / 9-10.2 / 11作为例外,但我特别困惑 10.2 / 13。我不知道10.2 / 13的意图。
您需要举例说明您不理解的内容。
应如何根据以下内容查找10.2 / 13中的示例 10.2 / 3-10.2 / 6?什么是10.2 / 13的意图,即什么是 其中10.2 / 13的情况被视为例外情况 10.2 / 3-10.2 / 6?
基于新算法的查找规则解耦了运行时问题(找到一个 来自编译时/查找问题的唯一对象(找到一个声明 一个名字指的是)。
以下是新措词的良好形式:
struct Z { int z; };
struct X : Z { };
struct Y : Z { };
struct A : X, Y { };
struct B : A {
using A::z;
};
声明using A::x;
在B引用的成员名称中引入
宣言Z::z
。在声明性语境中,这非常好。一个
仅当您将B::z
作为成员访问表达式访问时,错误才会升级
(5.2.5)。
关于成员指针案例的错误,不要感到难过。过去I did so too,相应的issue report实际上已将其变为C ++ 0x草案。幸运的是changed it back当他们注意到变化是错误的时候。