提升 static_vector 而不是 std::is_trivially_destructible
boost static_vector not std::is_trivially_destructible
根据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
时是微不足道的可破坏的(当 X
被破坏时没有循环 b
发生)。 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
的值是假的。这只是一个不正确的类型特征吗?
boost::container::static_vector<X, N>
派生自 boost::container::vector<X, ...>
class,其中有一些已定义的构造函数。即使它的所有主体在发布时都被编译器删除了,class 已经 not 可以轻易破坏:
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
这就是它不在当前增强实现中的技术原因。 std::is_trivially_destructible<boost::container::static_vector<int, 4> >::value
是否可以有另一种实现方式?是的,这是可能的,但我想它需要 boost::container::static_vector
对普通可破坏类型的专门化。
boost::static_vector
继承自 boost::vector
:https://github.com/boostorg/container/blob/develop/include/boost/container/static_vector.hpp#L106。由于 boost::~vector()
是非平凡的,因此 boost::vector
和 boost::static_vector
也是如此。
请注意,您的推理是错误的。在第二种情况下,无法优化析构函数调用,因为编译器看不到它的定义。尝试将 Y();
更改为 ~Y() { }
。一个简单的演示:https://godbolt.org/z/pg2xS4.
如果非平凡的析构函数调用没有可观察到的效果,为什么不允许编译器优化它们?
根据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
时是微不足道的可破坏的(当 X
被破坏时没有循环 b
发生)。 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
的值是假的。这只是一个不正确的类型特征吗?
boost::container::static_vector<X, N>
派生自 boost::container::vector<X, ...>
class,其中有一些已定义的构造函数。即使它的所有主体在发布时都被编译器删除了,class 已经 not 可以轻易破坏:
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
这就是它不在当前增强实现中的技术原因。 std::is_trivially_destructible<boost::container::static_vector<int, 4> >::value
是否可以有另一种实现方式?是的,这是可能的,但我想它需要 boost::container::static_vector
对普通可破坏类型的专门化。
boost::static_vector
继承自 boost::vector
:https://github.com/boostorg/container/blob/develop/include/boost/container/static_vector.hpp#L106。由于 boost::~vector()
是非平凡的,因此 boost::vector
和 boost::static_vector
也是如此。
请注意,您的推理是错误的。在第二种情况下,无法优化析构函数调用,因为编译器看不到它的定义。尝试将 Y();
更改为 ~Y() { }
。一个简单的演示:https://godbolt.org/z/pg2xS4.
如果非平凡的析构函数调用没有可观察到的效果,为什么不允许编译器优化它们?