sizeof std::aligned_storage 和 std::aligned_union

sizeof std::aligned_storage and std::aligned_union

给定以下代码:

#include <iostream>
#include <type_traits>

int main() {
    std::aligned_storage<sizeof(double), alignof(double)> storage;
    std::aligned_union<sizeof(double), double> union_storage;
    std::cout << sizeof(storage) << '\n';
    std::cout << sizeof(union_storage) << '\n';
    std::cout << sizeof(double) << '\n';
}

我希望 sizeof(storage)sizeof(union_storage) 大于或等于 sizeof(double),因为它们必须能够容纳 double。然而,I get the output

1
1
8

clang-3.8 和 gcc-5.3 都产生这个输出。
为什么 sizeof return 尺寸不正确?
如果我使用 placement new 将 double 放入 storageunion_storage 是否是未定义的行为?

std::aligned_storagestd::aligned_union 是类型特征,它们提供了一个成员 type,这是存储的实际类型。 因此,在实际特征类型的内存中放置一个 double 确实是 UB,因为它们是空类型,只有一个 typedef 成员。

#include <iostream>
#include <type_traits>

int main() 
{
    using storage_type = 
        std::aligned_storage<sizeof(double), alignof(double)>::type;
    using union_storage_type =
        std::aligned_union<sizeof(double), double>::type;

    storage_type storage;
    union_storage_type union_storage;

    std::cout << sizeof(storage_type) << '\n';
    std::cout << sizeof(union_storage_type) << '\n';
    std::cout << sizeof(storage) << '\n';
    std::cout << sizeof(union_storage) << '\n';
    std::cout << sizeof(double) << '\n';
    return 0;
}

This gives:

8
8
8
8
8

注:如@T.C。正确注释:C++14 为 std 类型特征(即 std::aligned_storage<L, A>::type === std::aligned_storage_t<L,A>)提供以 _t 结尾的别名模板。好处是

  1. 模板相关上下文中没有 typename
  2. 减少打字。 ;)