Presque toutes les fonctions sont supposées être potentiellement lancées, à moins que vous n'utilisiez explicitement une fonction de type noexcept
spécificateur. Les exceptions sont pour vos propres définitions de delete
(fonctions de désallocation), et certaines fonctions membres spéciales : constructeurs, destructeurs et opérateurs d'affectation. (C++17)
De [except.spec]
Si la déclaration d'une fonction n'a pas d'objet noexcept-specifier la déclaration a un potentiel de lancer à moins qu'il ne s'agisse d'un destructeur ou d'une fonction de désallocation, ou qu'elle soit proposée par défaut lors de sa première déclaration, auquel cas la spécification de l'exception est telle que précisée ci-dessous et aucune autre déclaration pour cette fonction ne doit avoir une noexcept-specifier .
Constructeurs
Sont implicitement noexcept
à moins que toute initialisation effectuée pour un membre quelconque (ou un membre d'un membre, etc.) soit susceptible de lancer
Destructeurs
sont implicitement noexcept
à moins que tout destructeur d'un sous-objet potentiellement construit soit potentiellement lanceur.
Opérateurs d'assignation
Sont implicitement noexcept
sauf si l'utilisation de l'assignation à l'intérieur est potentiellement lancinante.
Voici un exemple de code qui démontre ce qui précède ( clang 6.0.0 , gcc 8.0.0 ) :
int foo() { return 1; }
int bar() noexcept{ return 1; }
struct Foo{};
struct Bar{
Bar(){}
};
int main()
{
static_assert(noexcept(bar()));
static_assert(!noexcept(foo()));
static_assert(noexcept(Foo()));
static_assert(noexcept(Foo().~Foo()));
static_assert(noexcept(Foo().operator=(Foo())));
static_assert(!noexcept(Bar()));
Bar b;
static_assert(noexcept(b.~Bar()));
}
Une raison de plus d'utiliser =default
ou permettre au compilateur de générer ses propres versions de vos fonctions membres spéciales par omission.