为什么我们不能通过class-member-access表达式使用嵌套类型?

时间:2014-10-25 10:14:08

标签: c++ types

我试图理解为什么我们不能通过class-member-access表达式使用嵌套类型。 例如,我们有以下类:

struct U
{
    struct A
    {
        static int v;
        int a;
    };

    struct B
    {
       int b;
    };
};

U a;

typedef a.A T; //'a' does not name a type

int main()
{
    std::cout << typeid(a.A).hash_code(); //invalid use of 'struct U::A'
    struct a.A b;                         //trying to declare a variable of type U::A
                                          //error: expected unqualified-id before '.' token
    a.A b;                                //the same as above
                                          //error: expected unqualified-id before '.' token
    a.A.v = 5;                            //error: expected unqualified-id before '.' token
}

DEMO

标准说:

N3797::5.2.5/2 [expr.ref]部分

  

对于第一个选项(点),第一个表达式应该是完整的   班级类型。对于第二个选项(箭头),第一个表达式应为   有指向完整类类型的指针。表达式E1-> E2是   转换为等效形式(*(E1))。E2; 5.2.5的其余部分   将只解决第一个选项(点)。在任何一种情况下,    id-expression应该命名该类或其基类之一的成员

然而,N3797::9.2/1 [class.mem]部分给出了类成员的定义:

  

类的成员是数据成员,成员函数(9.3),嵌套   类型和枚举器。

所以我无法看到嵌套类型的这种使用限制。为什么不呢?

3 个答案:

答案 0 :(得分:5)

在[expr.ref]

中向下看
  

(4.4)如果E2是嵌套类型,则表达式E1.E2是不正确的。

答案 1 :(得分:2)

标准是讨论变量所代表的对象的类型 您需要访问类的范围,而不是变量。

要从U访问嵌套类的成员,您需要从该类型创建成员,有两种方法可以做到这一点:

struct U
{
    struct A
    {
        static int v;
        int a;
    } VarNameForA;

    struct B
    {
       int b;
    };
    B VarNameOfB;
};

使用范围运算符::来访问类型。

以下是您尝试的所有内容:

U a;

typedef decltype(a) varType;
typedef varType::A  nestedType;

int main()
{
    std::cout << typeid(U::A).hash_code(); 
    struct U::A b;                        
    U u;
    u.VarNameForA.a = 5;
    u.VarNameOfB.b = 6;

    U::A::c = 3;                          

}

对于使用运算符dot (.)的成员,对于类型和静态,您需要使用scope ::运算符。

答案 2 :(得分:2)

您尝试使用a.A作为类型说明符。

您引用的类成员访问规则(5.2.5)仅对表达式有效,不适用于类型说明符和类型名称(5/1:“表达式是一系列运算符和指定计算的操作数。表达式可能会产生一个值,并可能导致副作用。“)。

您必须在标准的第7.1.6节中查看类型说明符的规则。在那里没有使用运算符.。精心设计的类型(7.1.6.3)使用::来组合类型名称上的组件。

clang 错误消息比您从编译器获得的错误消息更明确:“不能在类型上使用点运算符”)。

顺便说一句,你的U是一个空结构(没有数据),只有嵌套类型的定义。这就是a.A.v = 5;也是一个错误的原因:这里没有可以分配的左值。