使用std :: aligned_storage对齐静态数组

gor*_*ill 6 c++ arrays pointers memory-alignment c++11

我正在尝试使用std :: aligned_storage模式实现简单静态数组的16字节对齐:

#include <type_traits>
int main()
{
    const size_t SIZE = 8;
    using float_16 = std::aligned_storage<sizeof(float) * SIZE, 16>::type;
    float_16 mas;
    new(&mas) float[SIZE];//Placement new. Is this necessary? 

    mas[0]=1.f;//Compile error while attempting to set elements of aligned array
}
Run Code Online (Sandbox Code Playgroud)

我得到以下编译错误:

«mas [0]»中«operator []»不匹配

然后我尝试使用显式指针转换:

float* mas_ = reinterpret_cast<float*>(mas); 
Run Code Online (Sandbox Code Playgroud)

但这也会产生编译错误:

从类型«float_16 {aka std :: aligned_storage <32u,16u> :: type}»无效转换为类型«float*»

任何人都可以建议我如何正确使用std :: aligned_storage对齐静态数组?

Jar*_*d42 8

你可以使用:

float* floats = new (&mas) float[SIZE];
Run Code Online (Sandbox Code Playgroud)

然后你可以使用:

floats[0] = 1.f;
Run Code Online (Sandbox Code Playgroud)

完全没有reinterpret_cast:)


R. *_*des 5

mas不是指针.reinterpret_cast必须仅涉及指针,引用或整数类型,并且仅在某些组合中:指向和来自整数类型的指针,指针指针,对引用的引用或自身的整数类型.在这种情况下,您试图std::aligned_storage<32u, 16u>::type将一个指针放到指针上.你可以从中得到的最好的是对指针转换的引用,但是不允许†.

尝试将其地址转换为另一种指针类型:reinterpret_cast<float*>(&mas);.


†为了好玩:你可能得到的最糟糕的是如果std::aligned_storage<32u, 16u>::type是指针类型.令人怀疑的是,因为32字节指针并不常见,但它可能发生std::aligned_storage<8u, 8u>::type在例如非常讨厌的标准库中.我们称之为Hell ++.因此,在Hell ++中它会编译得很好,你最终会将指针类型转换为另一个指针类型,然后对其进行所有恶意​​操作,如解除引用它.这将是灾难性的,因为如果std::aligned_storage<32u, 16u>::type是指针类型,对象将没有存储的地址,但它们将存储.

  • 哦拜托.我会直言不讳.在开始搞乱`reinterpret_cast`和`aligned_storage`之前,你需要学习一些基本的C++. (5认同)
  • @gorill如果不是,请为您的标准库实现提交错误.(你可以通过reinterpret_casting指针作为一个整数并检查它是否可被16整除来测试它) (2认同)