#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'; }
}
后,gcc,clang和VS2015不会在下面的代码中忽略对move构造函数的调用。在我看来,§8.12[class.copy] / 31(N4140)的项目符号(31.2)中建立的条件得到满足。
a
请注意ActionBar ab = getActionBar();
ab.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#ff0000")));
是左值,但根据§12.8/ 32,重载决策
首先执行选择复制的构造函数,就好像对象是由rvalue指定的一样。也就是说,对move构造函数的调用是可以的。如果删除上面的移动构造函数的定义,则调用复制构造函数,但同样,它不会被省略!
我理解标准没有规定复制省略,但我很想知道是否有任何特殊条件可以证明这一事实,上面提到的三个编译器在这个特定的例子中避免了这种优化。
gcc的示例输出,来自上面的链接:
g ++ -std = c ++ 14 -O2 -Wall -pedantic -pthread main.cpp&amp;&amp; ./a.out
默认ctor
移动ctor
析构函数
陷入
析构函数
答案 0 :(得分:3)
根据12.8 [class.copy]第31段,第二个子弹可以省略抛出的局部变量的副本:
在 throw-expression 中,当操作数是非易失性自动对象(函数或catch子句参数除外)的名称时,其范围不会超出内 封闭 try-block (如果有的话),通过将自动对象直接构造到异常对象中,可以省略从操作数到异常对象(15.1)的复制/移动操作
似乎没有一个编译器使用这种优化。其中一个原因可能是因为努力更好地花在其他优化上,这根本不值得做。我认为标准中没有任何内容禁止这种优化。