抛出一个通过引用传递的临时参数
Throw a temporary argument passed by reference
inline void my_assert( bool cond, const std::exception &e = my_assert_failed() )
{
if ( !cond )
throw e;
}
标准确保:
A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.
对于抛出的临时对象:
The temporary persists as long as there is a handler being executed for that exception.
我可以推断传递给 my_assert
的临时文件会一直存在到 catch 块完成吗?
来自 N4296(最终 C++14 之后的初稿)[15.1p3]:
Throwing an exception copy-initializes (8.5, 12.8) a temporary object,
called the exception object. The temporary is an lvalue and is used
to initialize the variable declared in the matching handler (15.3).
所以你不能假设你的临时"survives the throw"。如果抛出,类型为 std::exception
的异常对象的复制构造函数将以 e
作为参数被调用。当控制离开包含对 my_assert
的调用的完整表达式时, e
绑定到的临时对象将被销毁(在正常 return 之后或作为堆栈展开的一部分,因为你有条件地抛出异常)。
根据[12.8p31.2]:
在某些情况下可以省略异常对象的复制构造,但这不是其中之一
— in a throw-expression (5.17), when the operand is the name of a
non-volatile automatic object (other than a function or catch-clause
parameter) whose scope does not extend beyond the end of the innermost
enclosing try-block (if there is one), the copy/move operation from
the operand to the exception object (15.1) can be omitted by
constructing the automatic object directly into the exception object
(强调我的)
inline void my_assert( bool cond, const std::exception &e = my_assert_failed() )
{
if ( !cond )
throw e;
}
标准确保:
A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.
对于抛出的临时对象:
The temporary persists as long as there is a handler being executed for that exception.
我可以推断传递给 my_assert
的临时文件会一直存在到 catch 块完成吗?
来自 N4296(最终 C++14 之后的初稿)[15.1p3]:
Throwing an exception copy-initializes (8.5, 12.8) a temporary object, called the exception object. The temporary is an lvalue and is used to initialize the variable declared in the matching handler (15.3).
所以你不能假设你的临时"survives the throw"。如果抛出,类型为 std::exception
的异常对象的复制构造函数将以 e
作为参数被调用。当控制离开包含对 my_assert
的调用的完整表达式时, e
绑定到的临时对象将被销毁(在正常 return 之后或作为堆栈展开的一部分,因为你有条件地抛出异常)。
根据[12.8p31.2]:
在某些情况下可以省略异常对象的复制构造,但这不是其中之一— in a throw-expression (5.17), when the operand is the name of a non-volatile automatic object (other than a function or catch-clause parameter) whose scope does not extend beyond the end of the innermost enclosing try-block (if there is one), the copy/move operation from the operand to the exception object (15.1) can be omitted by constructing the automatic object directly into the exception object
(强调我的)