我正在阅读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.
在回答了一些问题之后,我今天构建了这个实验
struct A {
bool &b;
A(bool &b):b(b) { }
~A() { std::cout << b; }
bool yield() { return true; }
};
bool b = A(b).yield();
int main() { }
Run Code Online (Sandbox Code Playgroud)
bfalse在true通过动态初始化将其设置为有值之前(由初始化为零).如果临时在b完成初始化之前被销毁,我们将打印false,否则true.
该规范说明临时在完整表达结束时被销毁.这似乎没有与初始化一起订购b.所以我想知道
false和true不同的运行?false用于上述的Clang打印,而GCC打印true.这让我很困惑.我是否错过了定义订单的规范文本?
c++ initialization language-lawyer temporary-objects order-of-execution