相关疑难解决方法(0)

列表初始化期间临时对象的生命周期

我一直认为,临时对象一直存在,直到完整表达结束.然而,这是a std::vector和数组的初始化之间的奇怪差异.

请考虑以下代码:

#include <iostream>
#include <vector>

struct ID{ 
  static int cnt;
  // the number of living object of class ID at the moment of creation:  
  int id;

  ID():id(++cnt){}

  ~ID(){
     cnt--;
  }
};

int ID::cnt=0;

int main(){

  int arr[]{ID().id, ID().id};
  std::vector<int> vec{ID().id, ID().id};

  std::cout<<" Array: "<<arr[0]<<", "<<arr[1]<<"\n";
  std::cout<<" Vector: "<<vec[0]<<", "<<vec[1]<<"\n";
}
Run Code Online (Sandbox Code Playgroud)

这个程序的输出有点意外(至少对我而言)意外:

 Array: 1, 1
 Vector: 1, 2
Run Code Online (Sandbox Code Playgroud)

这意味着,临时对象在整个初始化期间是活动的,std::vector但是在阵列的情况下它们被一个接一个地创建和销毁.我希望临时工可以活到完全表达int arr[]{ID().id, ID().id};完成之前.

该标准提到了一个关于临时对象的生命周期和数组初始化的例外(12.2).但是,我没有得到它的含义,也不知道为什么它适用于这种特殊情况:

有两种情况,临时表在与完整表达结束时不同的地方被摧毁.第一个上下文是调用默认构造函数来初始化数组的元素.如果构造函数具有一个或多个默认参数,则在构造下一个数组元素(如果有)之前,对默认参数中创建的每个临时的销毁进行排序.


不同编译器的结果概述(MSVS结果是NathanOliver的简称):

             Array    Vector
clang 3.8    1, 2      1, 2
g++ 6.1 …
Run Code Online (Sandbox Code Playgroud)

c++ g++ clang c++11

39
推荐指数
1
解决办法
1124
查看次数

C++全表达式标准措辞

在当前 (C++ 17) C++ 标准草案的 [intro.execution] 的第 12 段中写道:

一个完整的表达式是:

[...]

  • 不是另一个表达式的子表达式并且不是完整表达式的一部分的表达式。

如果语言构造被定义为产生函数的隐式调用,则出于此定义的目的,语言构造的使用被认为是表达式。[...]

“使用语言构造”的措辞是指构造本身被视为表达式,还是构造“使用”的隐式调用将被视为表达式?

我问这个是因为在同一段中有这个代码示例:

S s1(1);                   // full-expression is call of S?::?S(int)
Run Code Online (Sandbox Code Playgroud)

该评论将表明第二种解释是正确的。

但是,该段落明确指出init-declaratorfull-expression,这表明注释是错误的。

在过去(我相信甚至在 C++03 之前),这一段看起来是这样的(取自这个缺陷报告):

完整表达式是不是另一个表达式的子表达式的表达式。如果语言构造被定义为产生函数的隐式调用,则出于此定义的目的,语言构造的使用被认为是表达式。

[注意:C++ 中的某些上下文会导致对由表达式(5.19 [expr.comma])以外的句法构造产生的完整表达式进行评估。例如,在 8.6 [dcl.init] 中,初始化程序的一种语法是

( 表达式列表 )

但生成的构造是对构造函数的函数调用,并将表达式列表作为参数列表;这样的函数调用是一个完整的表达式。例如,在 8.6 [dcl.init] 中,初始化程序的另一种语法是

= 初始化子句

但同样,结果构造可能是对构造函数的函数调用,并以一个赋值表达式作为参数;同样,函数调用是一个完整的表达式。]

这是相信第二种解释就是预期的另一个原因。

我知道这对语言的理解没有影响,但我只想知道最初写这一段的人的意图是什么。

c++ standards language-lawyer

6
推荐指数
0
解决办法
896
查看次数

标签 统计

c++ ×2

c++11 ×1

clang ×1

g++ ×1

language-lawyer ×1

standards ×1