inline void my_assert( bool cond, const std::exception &e = my_assert_failed() )
{
if ( !cond )
throw e;
}
标准确保:
函数调用(5.2.2)中的引用参数的临时绑定将持续到包含该调用的完整表达式完成为止。
对于抛出的临时对象:
只要存在针对该异常执行的处理程序,临时就会持续存在。
我能否推断传递给my_assert
的临时值会一直存在,直到catch块结束?
答案 0 :(得分:9)
从N4296(最终C ++ 14之后的初稿)[15.1p3]:
抛出异常copy-initializes(8.5,12.8)一个临时对象, 称为异常对象。临时是左值并且被使用 初始化匹配处理程序(15.3)中声明的变量。
所以你不能认为你的临时“幸存下来”。如果抛出,将使用std::exception
作为参数调用类型为e
的异常对象的复制构造函数。当控件离开包含对e
的调用的完整表达式时(在正常返回之后或作为堆栈展开的一部分,因为您有条件地抛出异常),my_assert
绑定的临时将被销毁)。
在某些情况下,可以省略异常对象的复制构造,但根据[12.8p31.2],这不是其中之一:
- 在throw-expression(5.17)中,当操作数是a的名称时 非易失性自动对象(除了函数或catch子句之外的) 参数),其范围不会超出最内层的末尾 封闭try-block(如果有的话),复制/移动操作 异常对象(15.1)的操作数可以省略 将自动对象直接构造到异常对象
(强调我的)