Рассмотрим фрагмент:Генерирование RValue
try {
Foo f;
throw std::move(f);
}
catch (Foo& f) { }
[expr.throw] говорит, что:
тип объекта исключения определяется путем удаления верхнего уровня CV-классификаторов из статического типа операнда и отрегулировать тип из «массива Т» или «функции, возвращающей Т», на «указатель на Т» или «указатель на функцию возврата Т», соответственно.
который будет Foo&&
. Объект исключения затем инициализируется в соответствии с [except.throw]:
вызов исключения копирования инициализирует (8.5, 12.8) временный объект, называемый объект исключение. Временной значение является значением lvalue и используется для инициализации переменной, указанной в соответствующем обработчике (15.3). Если тип объекта исключения был бы неполным или указателем на неполный тип, отличный от (возможно, cv-qualified)
void
, программа плохо сформирована.
Это наводит меня на мысль о том, что объект исключения инициализируется как:
Foo&& __exception_object = std::move(f);
и что обработчик не будет соответствовать. Однако, как gcc, так и clang действительно ловят это исключение. Итак, каков фактический тип объекта исключения здесь? Если Foo
, почему?
Почему downvote? – Barry