在下面的代码片段中没有省略move构造函数有什么特殊的原因吗?
Is there any special reason why the move constructor is not elided in the snippet shown below?
gcc, clang和VS2015在抛出对象a
之后不会忽略对下面代码中的move构造函数的调用。在我看来,§8.12[类]的要点(31.2)所确立的条件。copy]/31 (N4140)
#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'; }
}
注意a
是一个左值,但根据§12.8/32,过载分辨率首先执行为副本选择构造函数的操作,就好像对象是由右值指定的一样。也就是说,调用move构造函数是可以的。如果删除上面move构造函数的定义,则调用复制构造函数,但同样没有省略它!
我知道copy-省略不是标准强制要求的,但是我很想知道是否有任何特殊的条件可以证明,在这个特定的例子中,上面提到的三个编译器避免了这种优化。
gcc的输出示例,来自上面的链接:
c++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp &&./a.o ut
默认男星
移动男星
析构函数
了
析构函数
根据12.8 [class]。第31段,第二个项目:抛出的局部变量的副本可以省略:
throw表达式中的,当操作数是非易失性自动对象(函数或catch子句参数除外)的名称时,该对象的作用域没有扩展到最内层的末尾包含try-block(如果有的话),通过将自动对象直接构造为异常对象
,可以省略从操作数到异常对象(15.1)的复制/移动操作。
似乎没有一个编译器使用这种优化。一个原因可能是,只要把精力花在其他优化上,就不值得这么做。
相关文章:
- 是什么让放置新调用对象的构造函数?
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 使用基类指针调用基类的值构造函数的语法是什么?
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- 构造函数后面的宏.什么意思?
- C++构造函数内部会发生什么?
- 用相同的参数声明两个构造函数的最偶像化的方法是什么?
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 我是否为邪恶刽子手的构造函数错过了什么?
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 什么时候用指针调用C++类构造函数
- 这个构造函数是做什么的
- 将复制构造函数设置为private和=delete有什么区别
- 我不明白在这个例子中什么时候调用构造函数
- 在C++中,从构造函数中将字符串文本分配给成员const char*变量时会发生什么
- c++ 17 中结构自动定义构造函数的规则是什么?
- 在C++中初始化带有和不使用构造函数调用的对象有什么区别
- 指示汇编时间叫什么构造函数
- 在这种情况下调用什么构造函数
- 使用什么构造函数