基于C++ ISO标准的name与variable概念区别是什么?
根据C++ ISO Draft (2020) 6.1(基础)章节规定:
A name是对identifier(标识符,5.10)、operator-function-id(12.6)、literal-operator-id(12.6.8)、*conversion-function-id(11.4.7.2)或template-id(13.3)的使用,用于指代某一实体或标签(8.7.5、8.2)。
所有指代实体的name都由declaration(声明)引入;所有指代标签的name要么由goto语句(8.7.5)引入,要么由labeled-statement(带标签语句,8.2)*引入。
*variable(变量)*由非静态数据成员之外的引用声明或对象声明引入,若变量存在名称,则该名称指代对应的引用或对象。
二者属于完全不同层面的概念,核心差异可以归纳为3点:
概念属性完全不同
name是语法层面的标识符号,本身只是用来指向其他目标的代号,不具备程序执行层面的实体属性。而variable是运行/编译层面的程序实体,本身就是占用存储(或绑定到存储)、有类型、有值属性的实际程序元素。
name可指代的目标范围远大于变量:除了变量之外,它还可以指代函数、类、模板、标签、转换函数、运算符重载等各类实体,这些目标都不属于variable范畴。二者不是一一对应关系
一个variable可以对应0个或多个name:- 无name的variable:比如函数声明
void test(int)中未命名的int参数、for (int = 0; ; )循环中未命名的计数变量、函数返回的临时变量等,这些都是合法的variable,但不存在对应的name。 - 多name对应同一个variable:比如引用绑定的场景
int a = 10; int &ref = a;,a和ref是两个不同的name,但指代的是同一个int类型的variable实体。
反过来,一个name永远有明确的指代目标,但这个目标大概率不是variable。比如std::string是name,指代的是标准库字符串类,不是变量;operator+是name,指代的是加法运算符重载,也不是变量。
- 无name的variable:比如函数声明
交集场景下的定位差异
当name指代variable时,二者是「指代符号」和「被指代实体」的关系,完全不是同一个东西。举个最常见的例子:
int var = 1; { int var = 2; std::cout << var; // 输出2 }
这段代码里出现了两个名为var的name,分别处于外层和内层作用域,各自指代两个不同的int变量实体。作用域查找、名字隐藏这些规则都是作用于name这个符号层面,而非variable实体层面。
内容的提问来源于stack exchange,提问作者user15071942

