18

我正在阅读 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{};
}

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


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

new array(); /* CDCD or CCDD ?? */

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

4

1 回答 1

2

我不认为有矛盾。

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

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

鉴于 1.9p10 等,编辑上述内容可能不正确。

于 2011-06-11T18:56:54.240 回答