Considérons le fragment:Lancer une rvalue
try {
Foo f;
throw std::move(f);
}
catch (Foo& f) { }
[expr.throw] dit que:
le type de l'objet d'exception est déterminée par élimination de tout niveau supérieur cv-qualificatifs à partir du type statique de l'opérande et en ajustant le type de "array of T" ou "fonction retournant T" à "pointeur sur T" ou "pointeur sur fonction retournant T", respectivement.
qui serait Foo&&
. L'objet d'exception est alors initialisé en fonction de [except.throw]:
lancer une exception copy-initialise (8.5, 12.8) d'un objet temporaire, appelé l'objet d'exception . Le temporary est une lvalue et est utilisé pour initialiser la variable déclarée dans le gestionnaire correspondant (15.3). Si le type de l'objet exception serait un type incomplet ou un pointeur vers un type incomplet autre que (éventuellement qualifié cv)
void
le programme est mal formé.
Cela me porte à croire que l'objet d'exception est initialisé comme:
Foo&& __exception_object = std::move(f);
et que le gestionnaire ne correspondrait pas à. Cependant, gcc et clang capturent cette exception. Alors, quel est le type réel de l'objet d'exception ici? Si Foo
, pourquoi?
Pourquoi le downvote? – Barry