Допустимо ли исключение prvalue в выражениях броска - PullRequest
0 голосов
/ 28 августа 2018

В §[except.throw] стандарт гласит, что генерирование исключения копирует-инициализирует объект исключения из выражения выброса

Создание исключительной копии инициализирует (11.6, 15.8) временный объект, называемый объектом исключения

Почему тогда следующий код компилируется на 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)

Инициализация копии не включает ни одного случая (из того, что мне кажется), который имеет право на исключение prvalue. Почему тогда приведенный выше код компилируется в C ++ 17?

1 Ответ

0 голосов
/ 28 августа 2018

Из недавнего проекта стандарта

11,6 [dcl.init] / 15

Инициализация, которая происходит в форме инициализатора скобок или равных или условие (9.4), а также при передаче аргумента, возврате функции, вызове исключения (18.1), обработке исключения (18.3) и инициализации составного элемента (11.6.1) называется copy-initialization.

Итак, T x = T(); является примером инициализации копирования. Так же бросает исключение и многие другие случаи.

Что делает инициализация копирования, определено в других частях 11.6 (наряду с другими формами инициализации). Соответствующий раздел о значениях в инициализаторах:

11,6 [dcl.init] /17.6.1

Если выражение инициализатора является prvalue, а cv-неквалифицированная версия типа источника является тем же классом, что и класс назначения, выражение инициализатора используется для инициализации объекта назначения

это также известно как гарантированное исключение. Если выражение инициализатора является выражением prvalue соответствующего типа, выражение prvalue используется для непосредственного создания цели инициализации.

...