当子表达式创建数组时,其中的临时数会发生什么?

Joh*_*itb 18 c++ standards temporary lifetime c++11

我正在阅读FDIS的这两段(12.2p {4,5}):

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

第二个上下文是引用绑定到临时的.引用绑定的临时值或作为绑定引用的子对象的完整对象的临时值在引用的生命周期内持续存在,除了:[...]

  • 函数调用(5.2.2)中的引用参数的临时绑定将持续到包含该调用的完整表达式完成为止.

这两个似乎与以下案例相矛盾

struct A {
  A() { std::cout << "C" << std::endl; }
  ~A() { std::cout << "D" << std::endl; }
};

struct B {
  B(A const& a = A()) { }
};

typedef B array[2];

int main() {
  array{};
}
Run Code Online (Sandbox Code Playgroud)

这个输出是否会CDCD按照第一个上下文的要求输出,还是CCDD按照第二个上下文的要求输出?GCC似乎遵循第二个上下文描述和输出CCDD.我忽略了一些重要的事情吗?


编辑:我不认为它需要C++ 0x.new我的问题也影响了这个表达式:

new array(); /* CDCD or CCDD ?? */
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,GCC遵循第一个上下文和输出CDCD.

n. *_* m. 2

我不认为这有什么矛盾。

5.2.2 清楚地说明了什么是函数调用。函数调用是一个后缀表达式,后跟括号,其中包含可能为空、以逗号分隔的表达式列表,这些表达式构成函数的参数。

程序中的任何地方似乎都没有函数调用B::B(A const&),所以我不明白第二段如何应用。

编辑上面可能是不正确的,考虑到 1.9p10 等。

  • 1.9p10 适用:“完整表达式是不是另一个表达式的子表达式的表达式。如果定义语言构造来生成函数的隐式调用,则对该语言构造的使用将被视为以下表达式的表达式:该定义的目的。” 请注意,在我的示例中,“array{}”已经是一个表达式(函数式转换),“new array()”(新表达式)也是如此。 (2认同)