2017-09-29 6 views
0

は、第二の解雇ではなく:デフォルトで保護されたデストラクタを持つクラスは簡単に破壊できないが、派生クラスは?最初の静的アサーションexemple以下で

#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,""); 

(GCC、クラン、MSVC、ellccで確認)

trivially_destructibleことができない理由を私は理解していません、 Bの中にはBがありますが、Bはやや破壊的です。

[class.dtor]

それはユーザが提供されない場合、デストラクタは自明であり、これはC++アクセシビリティがmentionnedされていない標準、これらの2項と矛盾であると思われますもし:

(6.1) - そのクラスの直接の基底クラスのすべての些細なデストラクタを持っている、と

- デストラクタが virtual

(6.2)ではありません

(6.3) - そのクラスの非静的データメンバーのすべてがクラス型(またはその配列)である場合、そのような クラスはそれぞれ、些細なデストラクタを持ちます。

[dcl.fct.def.default]

機能がユーザー宣言はなく、明示的にデフォルトまたはその最初の宣言に を削除された場合ユーザ提供あります。

答えて

4

外部から見れば、Aは全く破壊的ではないです。デストラクタはprotectedなので、A* ptrがある場合は、delete ptrを呼び出すとコンパイルが失敗します。セバスチャンREDLの答え補完するために

+0

ので 'のstd :: is_trivially_destructible ::値は== false'のは、T *は自明-破壊*痛い.... – Oliv

+1

それはSTD'として定義されています@Olivではないことを意味するものではありません。 :: is_destructible :: value &&(デストラクタは自明ではない) 'is_destructible 'は、おおよそ '宣言()として定義されています。 〜T() 'はコンテキストとは関係なく有効な式です。そして、デストラクタが保護されている場合はそうではありません。 –

-1

std::is_trivially_destructible<T>::value==falseはタイプがない自明-破壊であることを意味するものではありません。

テンプレートプログラミングで使用する場合は、標準ライブラリタイプの特性を使用せず、コンパイラ組み込み関数を直接使用する方がよいでしょう。 GCCとexempleについて:

#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),""); 
}; 
関連する問題