boost static_vector not std :: is_trivially_destructible

问题描述 投票:4回答:2

根据this example(左示例)

#include <array>
#include <boost/container/static_vector.hpp>

struct X {
  int k;
  std::array<int, 4>                      a;
  boost::container::static_vector<int, 4> b;
  ~X() = default;
};

int huh()
{
  std::array<X, 5> x;
  return 0;
}

boost::container::static_vector<T, N>是(当T被摧毁时没有发生b的循环),它看起来像X是平凡的可破坏的。 huh优化到xor eax, eax; ret(即return 0没有循环阵列。

当我使用具有非平凡析构函数的包含类型时(右边示例)

#include <array>
#include <boost/container/static_vector.hpp>

struct Y {
  ~Y();
};

struct X {
  int k;
  std::array<int, 4> a;
  boost::container::static_vector<Y, 4> b;
  ~X() = default;
};

int huh()
{
  std::array<X, 5> x;
  return 0;
}

发生了一个循环

    add     rbx, 1
    call    Y::~Y() [complete object destructor]
    cmp     rbx, r12
    jne     .L3

我认为到目前为止这是有道理的。无论实际存储了多少个对象,static_vector占用的内存都可以在不变的时间内释放。

令我惊讶的是,std::is_trivially_destructible<boost::container::static_vector<int, 4> >::value的价值是假的。这只是一种不正确的类型特征吗?

c++ boost typetraits destroy
2个回答
3
投票

boost::container::static_vector<X, N>派生自boost::container::vector<X, ...>类,它有一些定义的构造函数。即使编译器在发布中消除了它的所有主体,该类已经不是简单的可破坏的:

struct X
{
};

struct Y
{
    ~Y() = default;
};

struct Z
{
    ~Z() {};
};

static_assert(std::is_trivially_destructible<X>::value, ""); // Succeeds
static_assert(std::is_trivially_destructible<Y>::value, ""); // Succeeds
static_assert(std::is_trivially_destructible<Z>::value, ""); // Fails

这就是为什么它不在当前的boost实现中的技术原因。可以有另一种实施,其中std::is_trivially_destructible<boost::container::static_vector<int, 4> >::value是真的吗?是的,这是可能的,但我认为它需要boost::container::static_vector专门化为简单的可破坏类型。


1
投票

boost::static_vector继承自boost::vectorhttps://github.com/boostorg/container/blob/develop/include/boost/container/static_vector.hpp#L106。由于boost::~vector()是非平凡的,因此也是boost::vectorboost::static_vector


请注意,你的推理是错误的。在第二种情况下,析构函数调用无法优化,因为编译器没有看到它的定义。尝试将Y();更改为~Y() { }。一个简单的演示:https://godbolt.org/z/pg2xS4

如果没有可观察到的影响,为什么不允许编译器优化掉非平凡的析构函数调用呢?

© www.soinside.com 2019 - 2024. All rights reserved.