如果我有一个实现了move构造函数e
的类型的对象Error
,将std::move( e )
使用的move构造函数Error
来抛出“ duplicate” e
,那么它会避免制作该对象的实际副本吗?所以如果我有
Error e;
throw std::move( e );
的副本构造函数是否Error
被调用?当您的move构造函数为noexcept
(应该如此)而您的copy构造函数为不是时,这是很有意思的。
第15.1节[投掷除外]:
引发异常将副本复制(初始化为8.5,12.8)一个临时对象,称为异常对象。临时变量是一个左值,用于初始化在匹配处理程序中命名的变量。
当抛出的对象是一个类对象时,即使省略了复制/移动操作,也可以访问为复制初始化选择的构造函数和析构函数(12.8)。
第8.5节[dcl.init]:
初始化形式
T x = a;
,以及参数传递,函数返回,引发异常(15.1),处理异常(15.3)和聚合成员初始化(8.5.1)的过程称为复制初始化。[注意:复制初始化可能会调用移动(12.8)。—尾注]
第12.8节[class.copy]:
- 当满足或将要执行复制操作的省略标准时,除非源对象是函数参数,并且要复制的对象由左值指定,选择重载构造函数的重载分辨率为首先执行,就好像该对象是由右值指定的。
前述的复制删除标准包括以下内容(第12.8节[class.copy] / p31):
- 在throw-expression中,当操作数是非易失性自动对象(函数或catch子句参数除外)的名称时,其作用域不超出最里面的try块的末尾(如果有) ),可以通过将自动对象直接构造为异常对象来省略从操作数到异常对象(15.1)的复制/移动操作
异常的复制初始化可能会调用move构造函数来构造实际的异常对象(即使std::move(e)
未在throw
表达式中显式调用),但也不会构造其匹配处理程序(如果试图被值捕获)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句