理解令人困惑的typedef语法

Pra*_*rav 41 c c++ typedef language-lawyer

请考虑以下代码段

typedef int type;
int main()
{
   type *type; // why is it allowed?
   type *k ;// which type?
}
Run Code Online (Sandbox Code Playgroud)

我收到一个错误'k' is not declared in this scope.编译器解析type *ktype*和之间的乘法k.这个语法不是很混乱吗?

为什么type *typeC++标准允许?因为语法是这样说的?为什么?

Mik*_*our 23

type *type; // why is it allowed?
Run Code Online (Sandbox Code Playgroud)

C++ 11 3.3.2/1说:

名称的声明点紧接在其完整的声明者(第8条)之后和其初始化者(如果有的话)之前

因此,type在使用类型名称之后才会引入变量名称type; 类型名称是type声明者期间唯一可用的含义.

type *k ;// which type?
Run Code Online (Sandbox Code Playgroud)

局部变量名称隐藏全局类型名称,因此在此处选择.这在C++ 11 3.3.10/1中有描述:

名称可以通过嵌套声明性区域或派生类中的相同名称的显式声明来隐藏.

完全限定的类型名称::type当然仍然可用.

  • @PrasoonSaurav:名称范围在其声明之后开始的理由,而不是在它之前的某个时刻?我只能推测语言设计师在想什么,但这对我来说比任何其他选项更合理,即使它确实允许像`type*type;`这样稍微不稳定的代码. (2认同)

Dav*_*eas 15

问题实际上是关于何时将变量名称确定为标识符,并且语言确定它恰好在声明变量的代码中的点之后:

typedef int type;
int main() {
   type t;   // type refers to ::type
   int       // type still refers to ::type
   type;     // variable declared, this shadows ::type
   type + 1; // type is a variable of type int.
}
Run Code Online (Sandbox Code Playgroud)

其他上下文中也有类似的规则,只需要确定何时声明标识符.还有其他类似的情况,例如在类的初始化列表中:

struct test {
   int x;          // declare member
   test( int x )   // declare parameter (shadows member)
   : x(            // refers to member (parameter is not legal here)
        x )        // refers to parameter
   {};
};
Run Code Online (Sandbox Code Playgroud)

或者在成员函数定义中的标识符范围内:

struct test {
   typedef int type;
   type f( type );
};
test::type         // qualification required, the scope of the return type is
                   // at namespace level
test::f(
         type t )  // but the scope of arguments is the class, no qualification
                   // required.
{}
Run Code Online (Sandbox Code Playgroud)

至于决定的理由,我不能告诉你,但它是一致和简单的.