Si consideri il seguente programma:g ++ - 4.8.1 pensa che un distruttore esplicitamente dichiarata, senza specifica eccezione è sempre noexcept (vero)
#include <type_traits>
struct Thrower
{
~Thrower() noexcept(false) { throw 1; }
};
struct Implicit
{
Thrower t;
};
static_assert(!std::is_nothrow_destructible<Implicit>::value, "Implicit");
struct Explicit
{
~Explicit() {}
Thrower t;
};
static_assert(!std::is_nothrow_destructible<Explicit>::value, "Explicit");
Con g++-4.8.1
, c'è un errore di asserzione statico sul Explicit
- sembra pensare che ~Explicit()
sia noexcept
. Questo non corrisponde alle mie aspettative. Secondo §12.4.3:
Una dichiarazione di un distruttore che non ha una specifica delle eccezioni è implicitamente considerato di avere la stessa specifica delle eccezioni come una dichiarazione implicita
La cosa divertente ecco il controllo di Implicit
sembra comportarsi secondo la mia interpretazione di §15.4.14 (tramite §12.4.7).
... Se f è un ... distruttore ... è implicita specifica delle eccezioni specifica ... f ha la specifica delle eccezioni
noexcept(true)
se ogni funzione si richiama direttamente non ammette eccezioni.
g++-4.7
manca is_nothrow_destructable
, ho scritto il mio per controllare il comportamento in 4.7. Il programma sembra compilare perfettamente bene. Mi riservo il diritto per questo di essere completamente sbagliato e la fonte della mia confusione:
template <typename T>
struct is_nothrow_destructible
{
static constexpr bool value = noexcept(std::declval<T>().~T());
};
TL; DR: Perché g++-4.8.1
pensa che un distruttore esplicitamente dichiarata, senza specifica eccezione è semprenoexcept(true)
?
Aggiornamento: ho aperto un bug su questo: 57645. Se è davvero necessario aggirare questo problema, è possibile aggiungere una specifica di eccezione al distruttore (come nell'esempio Thrower
).
Ed è così che Andy Prowl ha scritto una risposta con 1000+ upvotes. –
@ H2CO3: lol, no, penso solo che questo sia un bug del compilatore e non ho alcuna possibilità di dire nulla di rilevante al riguardo;) –