关于c ++:在非静态成员函数中使用时,非静态成员的名称是否依赖?

Is the name of a non-static-member dependent when used within a non-static member function?

在下面的示例中,GCC 5.0和Clang 3.6都需要typename关键字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<int n>
struct I
{
    typedef int Type;
};

template<typename T>
struct A
{
    int m;

    void f()
    {
        typedef typename I<sizeof m>::Type Type; // typename required
    }
};

这是由下面的措辞在C++ 11标准中覆盖的:

[temp.dep.type]/8

A type is dependent if it is

  • a simple-template-id in which either the template name is a template parameter or any of the template
    arguments is a dependent type or an expression that is type-dependent or value-dependent

因此,如果sizeof m是值相关的,那么I是依赖的。

[temp.dep.expr]/4

Expressions of the following forms are never type-dependent (because the type of the expression cannot be
dependent):

1
sizeof unary-expression

[temp.dep.constexpr]/2

Expressions of the following form are value-dependent if the unary-expression or expression is typedependent
or the type-id is dependent:

1
sizeof unary-expression

所以只有当m是依赖的时候,sizeof m才是依赖的。

[expr.prim.general]/8

Within the
definition of a non-static member function, an identifier that names a non-static member is transformed to a
class member access expression

因此,m是类成员访问表达式中的成员。

[temp.dep.type]/4

A name is a member of the current instantiation if it is

  • An id-expression denoting the member in a class member access expression (5.2.5) for which the type
    of the object expression is the current instantiation, and the id-expression, when looked up (3.4.5),
    refers to at least one member of the current instantiation or a non-dependent base class thereof.

因此,似乎m是当前实例化的成员。

[temp.dep.type]/5

A name is a member of an unknown specialization if it is

  • An id-expression denoting the member in a class member access expression (5.2.5) in which either

    • the type of the object expression is the current instantiation, the current instantiation has at least
      one dependent base class, and name lookup of the id-expression does not find a member of the
      current instantiation or a non-dependent base class thereof; or

    • the type of the object expression is dependent and is not the current instantiation.

因此,m不是未知专门化的成员—通过名称查找可以发现它是当前实例化的成员。

[temp.dep.expr]/3

An id-expression is type-dependent if it contains

  • an identifier associated by name lookup with one or more declarations declared with a dependent type,
  • a nested-name-specifier or a qualified-id that names a member of an unknown specialization

由于mint型,不是未知专业的成员,这些子弹都不会使id表达式m依赖。

[temp.dep.expr]/5

A class member access expression (5.2.5) is type-dependent if the expression refers to a member of the current
instantiation and the type of the referenced member is dependent, or the class member access expression
refers to a member of an unknown specialization.

m转换为类成员访问表达式时,它仍然不依赖,因为它不引用未知专门化的成员。

是否应将m视为从属?在相关说明中,是否应将this->m视为从属?那么std::declval().m呢?

编辑

最后,&A::m是否应该依赖?


如你所说,sizeof m转化为sizeof (*this).m。根据[temp.dep.expr]/5,只有当参数表达式是类型相关的(而不是类型相关的)时,sizeof才是相关的:

A class member access expression (5.2.5) is type-dependent if the
expression refers to a member of the current instantiation and the
type of the referenced member is dependent, or the class member access
expression refers to a member of an unknown specialization.

m的类型不依赖,并且表达式也不引用未知专门化的成员-[temp.dep.type]/6:

A name is a member of an unknown specialization if it is

  • An id-expression denoting the member in a class member access expression (5.2.5) in which either

    • the type of the object expression is the current instantiation, the current instantiation has at least one dependent base class, and
      name lookup of the id-expression does not find a member of a class
      that is the current instantiation or a non-dependent base class
      thereof; or
    • the type of the object expression is dependent and is not the current instantiation.

虽然(*this)的类型是依赖的,但它是当前的实例化。名称查找应该发现m是当前实例化的成员。

因此,*this不依赖于类型,因此sizeof (*this).m不依赖于类型。(sizeof m也不依赖于函数定义的任何非静态数据成员初始值设定项,这是我在第二个已删除的答案中意外涉及的)。

为了使sizeof std::declval().m依赖,std::declval().m必须依赖于类型。std::declval().m似乎与类型有关,但我不确定。正如我上面引用的[temp.dep.expr]/5中所述,表达式中的EDOCX1[3]唯一可能是未知专门化的成员,我们必须证明这一点。

A name is a member of an unknown specialization if it is

  • An id-expression denoting the member in a class member access expression (5.2.5) in which either

    • the type of the object expression is the current instantiation, the current instantiation has at least one dependent base class, and
      name lookup of the id-expression does not find a member of a class
      that is the current instantiation or a non-dependent base class
      thereof; or
    • the type of the object expression is dependent and is not the current instantiation.

事实如下:

通过限定名称查找找到的declval函数模板只有一个,但我们不知道该候选函数的返回类型是否是定义时的当前实例化。尤其是在这里,add_rvalue_reference可能有定义时不知道的专门化(类似于这个场景)。因此,因为我们不知道std::declval()是否是当前的实例化,(我们假设)它不是,这使得整个表达式类型依赖。

&A::m的格式为&合格ID,由[temp.dep.constexpr]/5涵盖:

An expression of the form &qualified-id where the qualified-id
names a dependent member of the current instantiation is
value-dependent.

[温度下降类型]/5:

A name is a dependent member of the current instantiation if it is a
member of the current instantiation that, when looked up, refers to at
least one member of a class that is the current instantiation.

显然,A::m是当前实例化的成员,因此&A::m与值相关。另外,&A::m是依赖于类型的:子表达式A根据〔temp.local〕等价于A,这是一个具有依赖模板参数的简单模板ID。


(P)The answer hinges on whether EDOCX1 English 0 can be looked up to determination that it is a member of the current instance.The ID-Expression EDOCX1 pental 0 is transformed to a class member access EDOCX1 original 2,meaning the rules for qualified name lookup within a class member access are applicable.(p)(P)一般来说,一种依赖性表达方式的类型不能确定。这不完全清楚是否应为EDOCX1拟订一个英文字母3和EDOCX1。1.An expression containing EDOCX1 original 5 is type-dependent,but both EDOCX1 genital 3 communal and EDOCX1 sil 4 nambiguously name the current instantiation.(p)字母名称(P)The expression EDOCX1 pental 0 silian is indeed not type-dependent,because it refers to a member of the current instantiation.(p)(P)1.In the context of a non-static member,EDOCX1 plus 0 is transformed into the class member access expression EDOCX1.(p)布尔奇1(P)The transformation occurs because EDOCX1 penal 0 is a member of class EDOCX1 penographic 13 commercial within a non-static-member of class EDOCX1 penal 13.(p)布尔奇1字母名称布尔奇1(P)The above example explicitly permits use of EDOCX1 commercial 5 within a EDOCX1 commercial 16 commercial expression within a non-static member.(p)布尔奇1(P)There fore EDOCX1 substantive 5 is type-dependent within the definition of a member function of a class template.(p)布尔奇1(P)然而,这一点是由[Temp.dep.expr]/5 quoted in the question所超越的。(p)字母名称(P)The expression EDOCX1 penographic 18 silian is also not type-dependent,because it is also a class member access expression which refers to a member of the current instantiation.(p)字母名称(P)The expression EDOCX1 penogical 20 has to be type-dependent,as the return type of EDOCX1 pental 22.could depended on the type of EDOCX1 pental 13.(p)布尔奇1(P)13.Therefore EDOCX1(英文)是将字母转换成英文25。(p)布尔奇1(P)This confirms that EDOCX1 penographic 25 silian is a dependent type,meaning that EDOCX1 penographic 13 is also dependent.(p)BLC1语言(P)So EDOCX1…28…is a type-dependent expression.It follows that EDOCX1 pental 20 is type-dependent because it contains the type-dependent subexpression EDOCX1(p)字母名称(P)The expression EDOCX1 penography 31 logically has to be type-dependent because it has the type EDOCX1 penography 33 nabel which is a dependent type.(p)(P)The expression EDOCX1 penographic 31 communal is transformed to EDOCX1 penographic 35 nable because EDOCX1 pental 13 is the injected class name-as shown above.(p)(P)The id-expression EDOCX1 penographic 37 nible is type-dependent according to[temp.dep.express]/3 because it contains a template-id EDOCX1 indicatoriginal 25.Therefore the expression EDOCX1 indicative 35 silian is type-dependent according to[temp.dep.express]/1.(p)字母名称(P)The expression EDOCX1 plus 40 welcx1 is transformed to EDOCX1 penalic lina 37 because EDOCX1 pental 13 welcx1 is the injected class name-as shown above.The expression EDOCX1 penographical 37 is further transformed to EDOCX1 penographic 45 welcx1 because EDOCX1 pental 37 names a non-static member of EDOCX1 penal 13.(p)(P)The id-expression EDOCX1 penographic 37 nible is type-dependent according to[temp.dep.express]/3 because it contains a template-id EDOCX1 indicatoriginal 25.The class member access expression EDOCX1 indicategory a 45 nio refers to member of the current instantiation,so[temp.dep.express]/5 applies but does not make the expression type-dependent-nor does it contradict[temp.dep.express]/3.(p)故障?(P)Given the interpretation above,an id-expression naming a member of EDOCX1 universal 13.qualified with EDOCX1 pensional 13 communal or EDOCX1 universal 25.would become type-dependent,which seems unnecessary and inconsistent.考虑到在同一背景下,一种类型的名称是EDOCX1,13个音标或25个音标。(p)(P)If the intention of[temp.dep.expr]/5 is that EDOCX1 universal 2 is not type-dependent,then it follows that EDOCX1 universifical 45 should also be type-dependent.On the other hand,the intention could be that the name of a non-static member is always dependent.I've posted a question to STD-discussion to clarify this point:https://groups.google.com/a/isocp.org/forum//s35;]Topic/STD-discussion/gevz7mmxec8(p)