在下面的例子中,第一个静态断言被触发但不是第二个:
#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,Clang,MSVC,ellcc一起检查)
我不明白为什么A在B内部不能轻易破坏,而B是可以轻易破坏的。这似乎与C ++标准的这两段相矛盾,其中没有提及可访问性:
[class.dtor]
如果析构函数不是用户提供的,并且如果:
,则析构函数很简单(6.1) - 析构函数不是
virtual
,(6.2) - 其类的所有直接基类都有简单的析构函数,
(6.3) - 对于类的所有类型(或其数组)的非静态数据成员,每个都是这样的 class有一个简单的析构函数。
[dcl.fct.def.default]
如果用户声明并且没有明确默认或删除,则该功能是用户提供的 在第一次宣言上。
答案 0 :(得分:4)
简单地说,因为从外部的角度来看,A
根本不可破坏!析构函数是protected
,所以如果你有A* ptr
},调用delete ptr
将无法编译。
答案 1 :(得分:1)
补充Sebastian Redl答案: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),"");
};