2

我对标准 10.2/13 很困惑,

[注意:即使名称查找的结果是明确的,使用在多个子对象中找到的名称可能仍然是不明确的(4.11、5.2.5、5.3.1、11.2)。-结束注释] [示例:

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 = &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/13中的例子应该如何按照10.2/3-10.2/6查找?10.2/13的意图是什么,即10.2/13被认为是10.2/3-10.2/6的例外是什么情况?

请给我一些提示。非常感谢你。


经过一番思考,我认为 10.2/13 的意图对我来说更清楚了。

int B1::* mpB1 = &D::i; // 明确的

这应该是明确的,当前的编译器对此是错误的。这是明确的,因为指向类成员初始化的指针不涉及访问对象。

int D::* mpD = &D::i; // 模糊转换

这实际上意味着当从 int B1::*mpB1 转换为 int D::*mpD 时,由于基类不明确,转换是不明确的。

4

4 回答 4

4

对于 B1::* 情况,解释是明确的,只是从 B1 的开头到 i 的偏移量。

在 5.3.1/3 中:

struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*

所以诀窍是首先让 &D::i 成为 B1::* 类型。然后:

int B1::* mpB1 = &D::i; // Unambiguous

很简单。然后利息就来了:

int D::* mpD = &D::i; // Ambiguous conversion

这里的 RHS 是 B1::* 类型,需要进行转换,因为我们需要确定所引用的基数。

于 2011-01-20T02:55:22.287 回答
2

这:

int B1::* mpB1 = &D::i; // Unambiguous

是明确的,因为结果被分配给pointer to memberB 类的 a。
所以i选择哪个偏移量是相对于 B 成员(而不是父 D 类)并不重要。

所以这对你和我来说是明确的,但我认为编译器无法处理它。

于 2011-01-20T02:35:01.993 回答
0

对 ISO IEC 14882 2003 第 10 节的快速检查没有此示例或任何类似的示例。C++0x 是草案标准,VC++/GCC/CLang 不符合它。

我的猜测:这是新auto类型的一些副产品,在旧的 C++ 标准中找不到。

于 2011-01-20T02:00:44.960 回答
0

FWIW,我正在复制我给这个问题的usenet副本的答案:

大家好,
 
我对标准 n3225 10.2/13 感到非常困惑,  
[注意:即使名称查找的结果是明确的,使用在多个子对象中找到的名称可能仍然是不明确的(4.11、5.2.5、5.3.1 , 11.2).—结束注 ] [ 示例:  

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 = &D::i; // 明确的  

&D::i具有类型int B1::*,并且明确引用 的数据i成员  B1。如果您使用D对象取消引用它,或者将其分配给 a 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) 访问时才会出现错误。 

不要因为把成员指针的情况弄错了而感到难过。过去我也是这样做的,对应的issue report居然做成了C++0x草稿。幸运的是,当他们发现更改错误时,他们将其改回。

于 2011-01-20T23:21:55.410 回答