谁管理参数中的复制构造函数抛出的异常?
Who manages the exception thrown by a copy constructor in parameters?
假设我有这个功能
void foo() noexcept
{
// Safely noexcept code.
}
然后这个 class:
class Bar
{
Bar(const Bar&) { ... } // Is not noexcept, so might throw
// Non movable:
Bar(Bar&&) = delete;
};
现在,我需要修改 foo() 以按值接收 Bar:
void foo(Bar bar) // noexcept?
{
// Safely noexcept code
}
我假设 Bar 的复制是在调用 foo 之前完成的,所以 foo 的代码理论上仍然可以是 noexcept,
但我不确定在 C++ 级别是如何定义的。
foo 是否需要删除 noexcept 或在处理 Bar 时可能抛出的调用者?
它取决于调用模式(stdcall、farcall 等)或编译器吗?
更新:在其他问题中,我没有找到任何对调用约定的引用。这应该对行为产生影响。我想。
参见 [expr.call]/4:
The initialization and destruction of each parameter occurs within the context of
the calling function. [ Example: The access of the constructor, conversion functions or destructor is checked at the point of call in the calling function. If a constructor or destructor for a function parameter throws an exception, the search for a handler starts in the scope of the calling function; in particular, if the function called has a function-try-block (Clause 18) with a handler that could handle the exception, this handler is not considered. —end example ]
因此您仍然可以标记 foo
noexcept
,即使 bar
的初始化可能会抛出。调用函数不应该是noexcept
。 (也就是说,除非您同意在出现异常时终止程序。)
参数的构造发生在调用者中;一旦所有参数都已 built/converted 函数被调用。
可能不明显的一点是,在 C++ 中,即使是未传递参数的默认值表达式也会发生在调用者中:即
void foo(MyClass x=MyClass()) {
...
}
情况下的构造
foo();
仍然在调用方站点完成,在实际调用函数之前。
假设我有这个功能
void foo() noexcept
{
// Safely noexcept code.
}
然后这个 class:
class Bar
{
Bar(const Bar&) { ... } // Is not noexcept, so might throw
// Non movable:
Bar(Bar&&) = delete;
};
现在,我需要修改 foo() 以按值接收 Bar:
void foo(Bar bar) // noexcept?
{
// Safely noexcept code
}
我假设 Bar 的复制是在调用 foo 之前完成的,所以 foo 的代码理论上仍然可以是 noexcept, 但我不确定在 C++ 级别是如何定义的。 foo 是否需要删除 noexcept 或在处理 Bar 时可能抛出的调用者? 它取决于调用模式(stdcall、farcall 等)或编译器吗? 更新:在其他问题中,我没有找到任何对调用约定的引用。这应该对行为产生影响。我想。
参见 [expr.call]/4:
The initialization and destruction of each parameter occurs within the context of the calling function. [ Example: The access of the constructor, conversion functions or destructor is checked at the point of call in the calling function. If a constructor or destructor for a function parameter throws an exception, the search for a handler starts in the scope of the calling function; in particular, if the function called has a function-try-block (Clause 18) with a handler that could handle the exception, this handler is not considered. —end example ]
因此您仍然可以标记 foo
noexcept
,即使 bar
的初始化可能会抛出。调用函数不应该是noexcept
。 (也就是说,除非您同意在出现异常时终止程序。)
参数的构造发生在调用者中;一旦所有参数都已 built/converted 函数被调用。
可能不明显的一点是,在 C++ 中,即使是未传递参数的默认值表达式也会发生在调用者中:即
void foo(MyClass x=MyClass()) {
...
}
情况下的构造
foo();
仍然在调用方站点完成,在实际调用函数之前。