Class 具有默认的受保护析构函数,但派生的 class 是不可破坏的?
Class with defaulted protected destructor not trivially-destructible but derived class is?
在下面的例子中,第一个静态断言被触发但第二个没有:
#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 不能 trivially_destructible,在 B 里面,而 B 是微不足道的可破坏的。这似乎与 C++ 标准的这两段矛盾,其中没有提到可访问性:
[class.dtor]
A destructor is trivial if it is not user-provided and if:
(6.1) — the destructor is not virtual
,
(6.2) — all of the direct base classes of its class have trivial destructors, and
(6.3) — for all of the non-static data members of its class that are of class type (or array thereof), each such
class has a trivial destructor.
[dcl.fct.def.default]
A function is user-provided if it is user-declared and not explicitly defaulted or deleted
on its first declaration.
简单的说,因为从外部来看,A
是不可破坏的!析构函数是protected
,所以如果你有a A* ptr
,调用delete ptr
会编译失败
补充 Sebastian Redl 的回答:std::is_trivially_destructible<T>::value==false
并不意味着类型是 not trivially-destructible.
所以如果在模板编程中使用它,最好不要使用标准库类型特征,而是直接使用编译器内在。例如 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),"");
};
在下面的例子中,第一个静态断言被触发但第二个没有:
#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 不能 trivially_destructible,在 B 里面,而 B 是微不足道的可破坏的。这似乎与 C++ 标准的这两段矛盾,其中没有提到可访问性:
[class.dtor]
A destructor is trivial if it is not user-provided and if:
(6.1) — the destructor is not
virtual
,(6.2) — all of the direct base classes of its class have trivial destructors, and
(6.3) — for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.
[dcl.fct.def.default]
A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration.
简单的说,因为从外部来看,A
是不可破坏的!析构函数是protected
,所以如果你有a A* ptr
,调用delete ptr
会编译失败
补充 Sebastian Redl 的回答:std::is_trivially_destructible<T>::value==false
并不意味着类型是 not trivially-destructible.
所以如果在模板编程中使用它,最好不要使用标准库类型特征,而是直接使用编译器内在。例如 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),"");
};