我发现两个相似的语句执行顺序不同(唯一的区别是下面的语句有一个额外的;)。析构函数的顺序不同。C++对此是否有相应的规范,或者它只是一种未指定的行为?
环境: GCC10
#include <iostream>
template <int num>
struct S {
S() {std::cout << "S(" << num << ")\n"; }
~S() {std::cout << "~S(" << num << ")\n"; }
};
int main() {
({S<1>(), S<2>();});
std::cout << "-----------------------------------\n";
({S<3>(), S<4>();;});
}输出:
S(1)
S(2)
~S(1)
~S(2)
-----------------------------------
S(3)
S(4)
~S(4)
~S(3)发布于 2020-10-26 11:22:39
这不是标准的C++。这是一个被称为statement expression的GCC扩展。括号中的复合语句可以出现在允许使用表达式的位置。如果用大括号括起的块中的最后一条语句是表达式语句,则此表达式的值也是整个语句表达式的值;否则,语句表达式的类型为void,并且没有值。
您的第一个示例大致相当于
([](){ return S<1>(), S<2>(); })();(这是一个创建并立即调用的lambda )。有一个逗号表达式可以创建S<1>和S<2>临时文件。S<1>被销毁,从技术上讲,S<2>被复制到返回值中--但是这个副本被省略了。如果不是因为这个拷贝省略,你会看到
S<1>()
S<2>()
S<2>(S<2>&&) // (1) move constructor
~S<2>() // (2) the original temporary is destroyed
~S<1>()
~S<2>() // the copy is destroyed outside of the lambda但是省略了(1)/(2)对,留下了您在示例中观察到的序列。
在第二个例子中,大括号中的最后一条语句不是表达式,所以整个东西也没有值。它大致相当于
([](){ S<3>(), S<4>(); return; })();这两个临时对象都是在lambda中创建和销毁的,通常的规则都适用--临时对象以相反的构造顺序销毁。
https://stackoverflow.com/questions/64530967
复制相似问题