在 §[except.throw]
中,标准规定抛出异常会从 throw 表达式复制初始化异常对象
Throwing an exception copy-initializes (11.6, 15.8) a temporary object, called the exception object
为什么下面的代码可以在 C++17 上编译?
class Exception {
public:
Exception() = default;
Exception(Exception&&) = delete;
Exception(const Exception&) = delete;
};
int main() {
throw Exception{};
return 0;
}
( https://wandbox.org/permlink/R3WfzfnBAORTLVSy )
复制初始化不包括任何符合纯右值省略条件的情况(从我看来)。为什么上面的代码可以在 C++17 中编译?
最佳答案
来自最近的 draft standard
11.6 [dcl.init]/15
The initialization that occurs in the form of a brace-or-equal-initializer or condition (9.4), as well as in argument passing, function return, throwing an exception (18.1), handling an exception (18.3), and aggregate member initialization (11.6.1), is called copy-initialization.
所以 T x = T();
是复制初始化的一个例子。抛出异常和许多其他情况也是如此。
11.6 的其他部分定义了复制初始化的作用(以及其他形式的初始化)。初始化器中纯右值的相关部分是:
11.6 [dcl.init]/17.6.1
If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object
这也称为保证省略。如果初始化表达式是匹配类型的纯右值表达式,则使用纯右值表达式直接构造初始化目标。
关于c++ - 抛出表达式中是否允许右值省略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52048348/