sizeof std :: aligned_storage和std :: aligned_union

nwp*_*nwp 1 c++ sizeof type-traits c++11

给出以下代码:

#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';
}
Run Code Online (Sandbox Code Playgroud)

我期望sizeof(storage)并且sizeof(union_storage)要大于或等于,sizeof(double)因为他们必须能够拥有一个double.但是,我得到了输出

1
1
8
Run Code Online (Sandbox Code Playgroud)

clang-3.8和gcc-5.3都产生这个输出.
为什么sizeof返回不正确的尺寸?
如果我使用放置新把一个double进入storageunion_storage将是未定义的行为吗?

Pix*_*ist 10

std::aligned_storage并且std::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;
}
Run Code Online (Sandbox Code Playgroud)

这给出了:

8
8
8
8
8
Run Code Online (Sandbox Code Playgroud)

注意:正如@TC正确指出的那样:C++ 14提供_t了以std类型特征结尾的别名模板(即std::aligned_storage<L, A>::type === std::aligned_storage_t<L,A>).好处是

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

  • 或者C++ 14中的`aligned_storage_t`等. (2认同)