c++ - 抛出表达式中是否允许右值省略

标签 c++ exception exception-handling c++17 prvalue

§[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/

相关文章:

exception-handling - 语言设计(异常(exception)): Why `try` ?

c++ - 此代码是否会释放为 MULTIMAP 分配的内存?

c++ - Matlab/C++ : segmentation fault on parallel computing with C++ Mex persistent objects (cannot convert handle)

c++ - 使用 ostream 无处打印

Java : Problems accessing and writing to file

javascript - 在 HTML5/javascript 中创建异常处理程序

c++ - 具有自动说明符和static_cast的基于范围的for循环

php - Laravel 5 中的 API 异常

c# - 如何为 'float method' 返回 null - 错误处理

ios - SWIFT iOS 中的崩溃报告