1

P1787对同一实体有很好的描述。

两个实体声明声明同一个实体,如果考虑到未命名类型的声明以引入它们的名称以用于链接目的,如果有的话([dcl.typedef],[dcl.enum]),它们对应([basic.scope.scope]) , 具有相同的目标范围,不是函数或模板参数范围,并且要么

  1. 它们出现在同一个翻译单元中,或者
  2. 它们都使用模块链接声明名称并附加到同一个模块,或者
  3. 它们都声明具有外部链接的名称。

所以,考虑这个例子:

// a.hpp
inline int& function(){
   static int value = 0; // #1
   return value;
}
----------------------
//b.cpp
#include "a.hpp"
void g(){
  auto&& rf = function();
}
----------------------
//c.cpp
#include "a.hpp"
int main(){
 auto&& rf0 = function();
}

除了注释说:

[注:具有外部或模块链接的内联函数或变量可以在多个翻译单元([basic.def.odr])中定义,但是一个具有一个地址的实体。因此,在此类函数的主体中定义的类型或变量是单个实体。--结束注释]

但是,让我们考虑value声明的 at #1。在b's TU 和c's TU 中,这两个 for 的声明value是对应的,它们具有相同的由 的复合语句引入的目标范围function。但是,局部变量没有任何链接,因此不会满足该列表中的任何项目符号。那么,为什么value在不同的两个翻译单元中(在函数体中)的两个声明声明了同一个实体?如何通过 P1787 中的规则来解释?

4

1 回答 1

2

程序的行为(假设满足通常的ODR约束)就好像有一个function. 无论哪个定义包含 的唯一(有效)声明value,当然只声明一个实体。

请注意,这种定义的奇异性是如此之强,以至于它能够使“两个不同”的lambda表达式产生相同的闭包类型,而无需任何链接的概念;在没有 [basic.link] 帮助的情况下,它当然能够出于对象身份的目的而禁止声明。

于 2020-12-10T14:40:08.540 回答