Les spécificateurs d'exception ont été dépréciés parce que les spécificateurs d'exception sont généralement une mauvaise idée . noexcept
a été ajouté parce qu'il s'agit de la seule utilisation raisonnablement utile d'un spécificateur d'exception : savoir quand une fonction ne le fera pas lance une exception. Il s'agit donc d'un choix binaire : les fonctions qui lancent des exceptions et celles qui n'en lancent pas.
noexcept
a été ajouté plutôt que de supprimer tous les spécificateurs de jet autres que throw()
parce que noexcept
est plus puissant. noexcept
peut avoir un paramètre qui, à la compilation, se résout en un booléen. Si le booléen est vrai, alors la fonction noexcept
bâtons. Si le booléen est faux, alors le noexcept
ne tient pas et la fonction peut être rejetée.
Vous pouvez donc procéder de la manière suivante :
struct<typename T>
{
void CreateOtherClass() { T t{}; }
};
Fait CreateOtherClass
lancer des exceptions ? Cela pourrait être le cas si T
peut le faire. Comment le savoir ? En procédant de la manière suivante :
struct<typename T>
{
void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; }
};
Ainsi, CreateOtherClass()
est lancé si le constructeur par défaut du type donné est lancé. Cela résout l'un des principaux problèmes des spécificateurs d'exception : leur incapacité à se propager dans la pile d'appels.
Vous ne pouvez pas le faire avec throw()
.
8 votes
D'après ceci bel article également
noexcept
peuvent faire l'objet de contrôles d'exécution. La principale différence entre les deux est que le fait de cassernoexcept
causesstd::terminate
tout en brisantthrow
causesstd::unexpected
. Le déroulement de la pile est également légèrement différent dans ces cas.0 votes
Il n'y a rien qui soit vérifié au moment de la compilation avec certaines spécifications d'exception et qui soit vérifié au moment de l'exécution avec d'autres. Il s'agit d'un mythe créé par les opposants aux spécifications d'exception du C++.