`T`是否总是与`std :: aligned_storage <sizeof(t),alignof(t)=“”>具有相同的大小和对齐方式

时间:2017-09-28 00:37:41

标签: c++ c++14 sizeof alignof

在什么情况下标准要求Tstd::aligned_storage<sizeof(T), alignof(T)>具有完全相同的大小和对齐方式?

我认为答案总是如此,但是从other SO answers today开始,我了解到,对于一些不起眼的T,它可能是实现定义的。如果实现支持扩展对齐类型,例如128位整数,那么如果我理解正确的话std::aligned_storage是否最终将具有128位对齐,则由实现决定。

还有其他类型T,问题的答案可能是实现定义的吗?

在我的应用程序中,我基本上有一个未知类型的元组std::tuple<T, U, V>,我希望能够获得成员T的{​​em>偏移,{{1这个元组中的{},U尽可能高效,理想情况是在编译时。

(我意识到这是一个非常奇怪的事情。我正在尝试修复一些现有代码,其中使用V将元组覆盖在“布局兼容”类型之上。不相关的对象之间的类型是非法的,违反了严格的别名规则。如果我能得到成员的抵消,那么我可以将非法演员分解出去。)

AFAIK,这在C ++ 14 reinterpret_cast中无法完成。但它可以非常接近,我的代码看起来像这样:

constexpr

在实验中,大多数现代编译器都会将其优化为常量,即使有相关的重新解释强制转换,#include <type_traits> #include <tuple> #include <utility> #include <memory> template <typename T> struct tuple_of_aligned_storage; template <typename... Ts> struct tuple_of_aligned_storage<std::tuple<Ts...>> { using type = std::tuple<std::aligned_storage_t<sizeof(Ts), alignof(Ts)>...>; }; template <typename T> using tuple_of_aligned_storage_t = typename tuple_of_aligned_storage<T>::type; template <typename S> struct offset_helper { // Get offset of idx'th member template <std::size_t idx> static std::ptrdiff_t offset() { constexpr tuple_of_aligned_storage_t<S> layout{}; // TODO: Do modern compilers optimize `layout` object out of the binary? // If so, this call is probably inlined. return reinterpret_cast<const char *>(&std::get<idx>(layout)) - reinterpret_cast<const char *>(&layout); } }; int main() { using T = std::tuple<int, float, double>; return offset_helper<T>::offset<0>(); // offset of 0'th member } 函数也不能完全标记为offset

在这里使用constexpr的重点是,即使元组的成员不是默认构造,也有非平凡的初始化等等,用std::aligned_storage替换它们使得它们可以在不改变布局的情况下进行简单的构造。元组。

但是,如果对于某些类型,交换std::aligned_storage的类型会改变大小或对齐方式,这可能会破坏我的整个方法并导致计算错误的偏移量。

0 个答案:

没有答案