2017-09-29 1 views
0

Im folgenden exemple die erste statische Behauptung gefeuert, aber nicht die zweite:Klasse mit einem default-geschützten Destruktor nicht trivial-zerstörbar, aber abgeleitete Klasse ist?

#include<type_traits> 
struct A{ 
protected: 
    ~A()=default; 
}; 
struct B:A{ 
    //this static assertion fails 
    static_assert(std::is_trivially_destructible<A>::value,""); 
}; 
//this static assertion succeeds 
static_assert(std::is_trivially_destructible<B>::value,""); 

(mit GCC geprüft, Clang, MSVC, ellcc)

Ich verstehe nicht, warum A nicht trivially_destructible sein kann, in B, während B trivialerweise zerstörbar ist. Dies scheint im Widerspruch zu diesen 2 Absätzen des C++ Standard zu sein, wo die Zugänglichkeit nicht erwähnt wird:

[class.dtor]

A destructor ist trivial, wenn es nicht vom Benutzer zur Verfügung gestellt ist und wenn:

(6,1) - der Destruktor nicht virtual ist,

(6,2) - alle direkten Basisklassen seiner Klasse haben triviale Destruktoren und

(6.3) - für alle nicht statischen Datenelemente ihrer Klasse, die vom Klassentyp (oder Array davon) sind, hat jede Klasse einen trivialen Destruktor.

[dcl.fct.def.default]

Eine Funktion wird Benutzer bereitgestellte wenn es vom Benutzer erklärt und nicht explizit vorgegeben oder gelöscht auf seiner ersten Erklärung.

Antwort

4

Einfach gesagt, weil von außen Sicht ist Aüberhaupt nicht zerstörbar! Der Destruktor ist protected, wenn Sie also eine A* ptr haben, wird das Aufrufen von delete ptr nicht kompilieren.

+0

So 'std :: is_trivially_destructible :: value == false' bedeutet nicht, dass T nicht * trivialer-zerstörbare * autsch .... – Oliv

+1

ist @Oliv Es wird als' std definiert ist :: is_destructible :: value && (Destruktor ist trivial) ', und' is_destructible 'ist definiert als ungefähr' declval (). ~ T() 'ist ein gültiger Ausdruck, unabhängig vom Kontext. Und das ist nicht der Fall, wenn der Destruktor geschützt ist. –

-1

Sebastian Redl Antwort ergänzen: std::is_trivially_destructible<T>::value==false bedeutet nicht, dass der Typ nichttriviale-zerstörbare ist.

Also, wenn man es in Template-Programmierung verwenden, ist es viel besser, keine Standard-Bibliotheksmerkmale zu verwenden, sondern den Compiler intrinsisch zu verwenden. Für exemple mit gcc:

#include<type_traits> 
struct A{ 
    protected: 
    ~A(){}; 
}; 
struct B:A{ 
    //Bad: fails while the fact that A is trivially destructible 
    //could be used to implement optimized function member in B. 
    static_assert(std::is_trivially_destructible<A>::value,""); 
    //Good: __has_trivial_destructor actualy return what is name says!! 
    static_assert(__has_trivial_destructor(A),""); 
}; 
Verwandte Themen