使用move构造函数抛出异常? (C ++)

时间:2014-08-27 18:34:32

标签: c++ exception move

如果我有一个e类型的对象Error来实现一个移动构造函数,那么抛出std::move( e )会使用Error的移动构造函数来复制“{{1}那么它是否避免制作对象的实际副本?所以,如果我有

e

是否会调用Error e; throw std::move( e ); 的复制构造函数?当你的移动构造函数是Error(应该是)时,这是有意义的,但你的复制构造函数不是。

1 个答案:

答案 0 :(得分:9)

§15.1[except.throw]:

  
      
  1. 抛出异常复制初始化(8.5,12.8)临时对象,   称为异常对象。该   temporary是一个左值,用于初始化匹配处理程序中指定的变量。

  2.   
  3. 当抛出的对象是类对象时,即使复制/移动操作被省略,也应该可以访问为复制初始化和析构函数选择的构造函数(12.8)。

  4.   

§8.5[dcl.init]:

  
      
  1. 形式出现的初始化      

    T x = a;

  2.         

    ,以及参数传递,函数返回,抛出异常(15.1),处理异常   (15.3),聚合成员初始化(8.5.1)称为复制初始化。 [注意:复制初始化可以调用移动(12.8)。 - 后注]

§12.8[class.copy]:

  
      
  1. 当满足或将满足复制操作的省略标准时,除了源的事实   object是一个函数参数,要复制的对象由左值,重载决策指定   选择首先执行复制的构造函数就好像对象是由右值指定
  2.   

上述复制省略标准包括以下内容(§12.8[class.copy] / p31):

  
      
  • throw-expression 中,当操作数是非易失性自动对象的名称时(除了   function或catch-clause参数),其范围不超出最内层的末尾   封闭 try-block (如果有的话),从操作数到异常的复制/移动操作   通过将自动对象直接构造到异常对象
  • 中,可以省略object(15.1)   

异常的复制初始化可以调用move-constructor来构造实际的异常对象(即使std::move(e)表达式中没有显式调用throw),也不会调用其匹配的处理程序(如果试图被价值所吸引。)