2017-09-29 56 views
0

在爲例第一靜態斷言以下燃煤而不是第二:具有默認的受保護的析構函數的類不是可以破壞的但派生類是?

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

(與海灣合作委員會檢查,鐺,MSVC,ellcc)

我不明白爲什麼不能trivially_destructible,在B裏面,而B是微不足道的破壞。這似乎是矛盾與這些2個段落C++標準,其中輔助功能不mentionned的:

[class.dtor]

析構函數是平凡的,如果它不是用戶提供的和如果:

(6.1) - 析構函數不是virtual

(6.2) - 所有類的直接基類的瑣碎有析構函數,和

(6.3) - 對於類的所有類型爲(或其數組)的所有非靜態數據成員,每個類都有一個簡單的析構函數。

[dcl.fct.def.default]

的函數被用戶提供如果是用戶聲明的和未明確拖欠或在其第一聲明刪除 。

回答

4

簡而言之,因爲從外部的角度來看,A根本不可破壞!析構函數爲protected,所以如果你有一個A* ptr,調用delete ptr將無法​​編譯。

+0

所以'的std :: is_trivially_destructible ::值== FALSE'並不意味着T是不平凡的* - *破壞....哎呦 – Oliv

+1

@Oliv它定義爲'性病:: is_destructible :: value &&(析構函數不重要)',並且'is_destructible '被定義爲大致'declval ()。 〜T()'是一個獨立於上下文的有效表達式。如果析構函數受到保護,情況並非如此。 –

-1

爲了補充塞巴斯蒂安·雷德爾答案:std::is_trivially_destructible<T>::value==false並不意味着該類型是平凡,破壞

因此,如果在模板編程中使用它,最好不要使用標準庫類型特徵,而要直接使用編譯器內在特性。對於爲例用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),""); 
}; 
相關問題