Bel*_*loc 14 c++ exception copy-elision c++14
抛出对象后,gcc,clang和VS2015不会在下面的代码中忽略对move构造函数的调用a.在我看来,满足§8.12[class.copy]/31(N4140)的项目符号(31.2)中确定的条件.
#include <iostream>
struct A
{
A() { std::cout << "Default ctor " << '\n'; }
A(const A& a) { std::cout << "Copy ctor" << '\n'; }
A(A&& a) { std::cout << "Move ctor" << '\n'; }
~A() { std::cout << "Destructor " << '\n'; }
};
int main()
{
try
{
A a;
throw a;
}
catch(A& a) { std::cout << "Caught" << '\n'; }
}
Run Code Online (Sandbox Code Playgroud)
请注意,这a是一个左值,但根据§12.8/ 32,首先执行重载决策以选择副本的构造函数,就像对象由rvalue指定一样.也就是说,对move构造函数的调用是可以的.如果删除上面的移动构造函数的定义,则调用复制构造函数,但同样,它不会被省略!
我理解标准没有规定复制省略,但我很想知道是否有任何特殊条件可以证明这一事实,上面提到的三个编译器在这个特定的例子中避免了这种优化.
gcc的示例输出,来自上面的链接:
g ++ -std = c ++ 14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
默认ctor
移动ctor
析构函数
抓住
析构函数
根据 12.8 [class.copy] 第 31 段,第二个项目符号,可以省略被抛出的局部变量的副本:
在throw 表达式中,当操作数是非易失性自动对象(函数或 catch 子句参数除外)的名称时,其作用域不超出最内层封闭try 块的末尾(如果有一个),通过将自动对象直接构造到异常对象中,可以省略从操作数到异常对象(15.1)的复制/移动操作
似乎没有一个编译器使用这种优化。原因之一可能是,只要将精力花在其他优化上更好,就根本不值得这样做。我认为标准中没有任何内容禁止这种优化。
| 归档时间: |
|
| 查看次数: |
256 次 |
| 最近记录: |