我在下面关于C ++标准中§9.3.1/ 3的观察中是否正确?

时间:2015-01-23 20:39:26

标签: c++ c++11 language-lawyer

§9.3.1/ 3(重点是我的):

  

当一个id-expression(5.1)不属于类成员访问时   语法(5.2.5)并不用于形成指向成员(5.3.1)的指针   在可以使用它的上下文中在类X的成员中使用   (5.1.1),如果名称查找(3.4)解析了id-expression中的名称   到某个类C的非静态非类型成员,如果是   id-expression可能被评估 C是X或X的基类,   id-expression被转换为类成员访问表达式   (5.2.5)使用(* this)(9.3.2)作为左侧的后缀表达式   这个。运营商。 [注意:如果C不是X或X的基类,则为类   成员访问表达式格式错误。 - 结尾注释]同样期间   名称查找,当在a的定义中使用unqualified-id(5.1)时   类X的成员函数解析为静态成员,枚举器   或嵌套类型的类X或基类X,   unqualified-id转换为qualified-id(5.1),其中   nested-name-specifier命名成员函数的类。

上述说明不应该更具体吗?我的意思是这样的:`如果id-expression可能被评估,如果C不是X或X的基类,那么类成员访问表达式就是格式错误。“

请注意,如果id-expression是未评估的操作数,即使C不是X,代码也是有效的,也不是X的基类,尽管在这种情况下,段落中提到的转换不会发生。

3 个答案:

答案 0 :(得分:6)

这个音符有点含糊不清,但我认为它应该是关于前一句的最后一部分的注释,就像它被写成:

  

如果id-expression可能被评估,或者C是X或X的基类,那么:

     
      
  • 使用(* this)(9.3.2)将id-expression转换为类成员访问表达式(5.2.5)作为左侧的后缀表达式。运营商。 [注意:如果C不是X或X的基类,则类成员访问表达式格式错误。 - 尾注]
  •   

如果读到这样的话,说明是完全正确的。

无论如何,笔记都不具有规范性,因此即使措辞留有余地,也不重要,因为它对任何C ++程序或实现都没有任何影响:没有程序变为由于本说明的措辞有效或无效,并且由于本说明,没有实施符合或不符合。在最坏的情况下,正如在这里发生的那样,理解标准变得更加困难,导致误解。

正如Columbo在评论中提到的那样,实施者的这种误解可能会导致不合规的实施,但这不是这里发生的事情。

答案 1 :(得分:1)

该注释基本上暗示如果您使用C::member作为变量(而不仅仅是确定其类型,对齐方式或大小),该程序显然是不正确的。

一个例子是

class C 
{
    int member;
};

class X
{
    void memfun()
    {
        // Note that 'this' can be used here

        C::member = 3; // member is potentially evaluated ([basic.def.odr]/2).
                       // Thus the expression is transformed into 
                       // (*this).member
                       // which is clearly ill-formed.
    }
};

该计划格式不正确,因为member没有做任何事情"做什么"使用X(它不是X的成员或其任何基类)并且可能会对其进行评估。
引用是恰当的(虽然是多余的)。

但是,为什么sizeof(C::member)不会形成错误?因为C::member无法进行评估。

  

表达式可能被评估,除非它是未评估的   操作数(第5条)或其子表达式。

和[expr.sizeof]:

  

操作数是表达式,是未评估的   操作数(第5条)或带括号的 type-id

因此,id-expression不会被转换。

答案 2 :(得分:1)

所以这个说明来自2005年的defect report 515,当时的措辞不同:

  

当id-expression(5.1.1 [expr.prim.general])不属于   类成员访问语法(5.2.5 [expr.ref])并不用于形成   指向成员的指针(5.3.1 [expr.unary.op])用于a的主体   类X的非静态成员函数或在mem-initializer中使用   对于类X的构造函数,如果名称查找(3.4.1   [basic.lookup.unqual])将id-expression中的名称解析为a   某些类C的非静态非类型成员,id-expression是   转换为类成员访问表达式(5.2.5 [expr.ref])   使用(* this)(9.3.2 [class.this])作为后缀表达式   左边的。运营商。 [注意:如果C不是X或X的基类,则   类成员访问表达式是不正确的。 - 后注]

并且已经进化,请注意当前措辞前的注释:

  

或C是X或X的基类,即id-expression

在此早期的措辞中没有出现

,因此更有意义的是要有澄清说明,此时说明似乎是多余的。