sizeof std :: aligned_storage和std :: aligned_union

时间:2016-05-15 22:58:16

标签: c++ c++11 sizeof typetraits

给出以下代码:

#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返回的尺寸不正确?
如果我使用展示位置新功能将double放入storageunion_storage那么这将是未定义的行为吗?

1 个答案:

答案 0 :(得分:10)

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为_t类型特征(即std)提供以std::aligned_storage<L, A>::type === std::aligned_storage_t<L,A>结尾的别名模板。好处是

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