Rozważmy następujący program:g ++ - 4.8.1 uważa, że jawnie deklarowane destructor bez specyfikacji wyjątków jest zawsze noexcept (true)
#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");
Z g++-4.8.1
, jest statyczna awarii twierdzenie na Explicit
- wydaje się, że ~Explicit()
jest noexcept
. To nie pasuje do moich oczekiwań. Według §12.4.3:
Deklaracja destruktora, że nie ma wyjątków specyfikacją jest niejawnie uważany mieć taki sam wyjątek specyfikacją jako dorozumiane oświadczenie
Najśmieszniejsze tutaj kontrola Implicit
wydaje się zachowywać zgodnie z moją interpretacją § 15.4.14 (poprzez §12.4.7).
... Jeśli f jest ... ... to destruktor niejawny wyjątek-specyfikacja określa ... f ma wyjątku specyfikacją
noexcept(true)
jeśli każda funkcja pozwala ona bezpośrednio wywołuje żadnych wyjątków.
g++-4.7
brakuje is_nothrow_destructable
, napisałem mój własny, aby sprawdzić zachowanie w 4.7. Program wydaje się kompilować idealnie dobrze. Zastrzegam sobie prawo do tego, aby być całkowicie błędne i źródłem mojego zamieszania:
template <typename T>
struct is_nothrow_destructible
{
static constexpr bool value = noexcept(std::declval<T>().~T());
};
TL; DR: Dlaczego g++-4.8.1
myśleć, że jawnie deklarowane destructor bez specyfikacji wyjątków jest zawszenoexcept(true)
?
Aktualizacja: Otworzyłem błąd na ten temat: 57645. Jeśli naprawdę potrzebujesz obejść ten problem, możesz dodać specyfikację wyjątku do destruktora (na przykład w przykładzie: Thrower
).
W ten sposób Andy Prowl napisał odpowiedź z ponad 1000 upvotes. –
@ H2CO3: lol, nie, po prostu myślę, że to jest błąd kompilatora i mam zero szansy, aby powiedzieć coś istotnego na ten temat;) –