为什么允许使用类型别名作为变量名?

问题描述

什么规则使得以下代码为compile without error

using integer = int;

struct Foo
{
    int integer;
};

int main() {
    Foo f;
    int integer;
    f.integer;
}

using当然不是#define integer int的简单替代,但是什么使这段代码显然格式正确,而int int;却使其格式错误?

解决方法

虽然可以访问在外部作用域中声明的名称,然后再隐藏该名称,这有点令人惊讶,但这只是范围规则的直接应用:

在块(9.3)中声明的名称是该块的本地名称;它具有块范围。它的潜在范围始于其 声明点(6.3.2),并在其块末尾结束。 [basic.scope.block]

反过来,名称声明的重点是:

紧随其完整的声明符(第11条)之后, 初始化程序(如果有)... [basic.scope.pdecl]

因此,当您执行integer integer时,尚未声明块作用域名称integer,这意味着您仍然可以看到全局integer。这也意味着您不能执行integer integer = (integer)0

更容易解释为什么int int无法编译。 int是一个关键字,因此没有句法规则可以将其声明为名称。它不符合“名字看起来”的规则。

有五种令牌:标识符,关键字,文字,运算符和其他分隔符。 [lex.token]

因为int是关键字,所以它不能是标识符,这意味着它不能是名称。

,

代码编译的原因是integer的使用在不同的范围中。

using integer = int; // #1

struct Foo
{
    int integer;  // #2
};

请注意,integer中的#1#2之间没有任何关系。这些用法之间没有冲突,而且它们的名称也可能不同。

Foo内,符号integer仅指代变量。如果要引用类型别名,可以在::之前加上前缀,如下所示:

struct Foo
{
  ::integer integer;  // ok
};

如果using声明和变量在 same 范围内,则会出现错误:

using integer = int; 
int integer;          // error,redefinition of symbol 
                      // as different kind of entity

struct Foo
{
    using integer = int; 
    int integer;         // error,redefinition of symbol 
                         // as different kind of entity
};

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...