C++ 抛出通过引用传递的临时参数

C++ 抛出通过引用传递的临时参数,c++,exception-handling,C++,Exception Handling,该标准确保: 在函数调用(5.2.2)中,临时绑定到引用参数的操作会一直持续到包含该调用的完整表达式完成为止 对于抛出的临时对象: 只要存在针对该异常执行的处理程序,临时异常就会持续存在 我是否可以推断传递给my_assert的临时文件在catch块完成之前仍然有效?来自N4296(最终C++14后的第一稿)[15.1p3]: 抛出异常副本会初始化(8.5,12.8)临时对象, 调用异常对象。临时值是一个左值,用于 初始化匹配处理程序(15.3)中声明的变量 因此,你不能假设你的临时“成功”。如

该标准确保:

在函数调用(5.2.2)中,临时绑定到引用参数的操作会一直持续到包含该调用的完整表达式完成为止

对于抛出的临时对象:

只要存在针对该异常执行的处理程序,临时异常就会持续存在

我是否可以推断传递给
my_assert
的临时文件在catch块完成之前仍然有效?

来自N4296(最终C++14后的第一稿)[15.1p3]:

抛出异常副本会初始化(8.5,12.8)临时对象, 调用异常对象。临时值是一个左值,用于 初始化匹配处理程序(15.3)中声明的变量

因此,你不能假设你的临时“成功”。如果抛出,将调用类型为
std::exception
的异常对象的复制构造函数,并将
e
作为参数。当控件离开包含对
my_assert
调用的完整表达式时,
e
绑定的临时变量将被销毁(在正常返回之后,或者作为堆栈展开的一部分,因为您有条件地抛出异常)

根据[12.8p31.2],有时可以省略异常对象的复制构造,但这不是其中之一:

-在抛出表达式(5.17)中,当操作数是 非易失性自动对象(函数或catch子句除外 参数),其范围不超出最内层 封闭try块(如果有),从 异常对象(15.1)的操作数可以通过 将自动对象直接构造到异常对象中


(强调我的)

throw执行其参数的副本,这样您就不会抛出临时参数。@user657267这是一个答案。答案很好,精确且可靠。编辑了问题,使之尖锐化为“在投掷中幸存”。
inline void my_assert( bool cond, const std::exception &e = my_assert_failed() ) 
{ 
    if ( !cond ) 
      throw e;
}