6

我正在尝试使用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
}

我收到以下编译错误:

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

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

float* mas_ = reinterpret_cast<float*>(mas); 

但这也会产生编译错误:

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

谁能建议我如何正确使用std::aligned_storage对齐静态数组?

4

3 回答 3

8

您可以使用:

float* floats = new (&mas) float[SIZE];

然后你可以使用:

floats[0] = 1.f;

完全没有reinterpret_cast:)

于 2013-09-05T17:56:26.610 回答
5

mas不是指针。reinterpret_cast必须只涉及指针、引用或整数类型,并且仅涉及某些组合:指向和来自整数类型的指针、指向指针的指针、对引用的引用或指向自身的整数类型。在这种情况下,您试图将 an 大小写std::aligned_storage<32u, 16u>::type为指针。您可以从中获得的最好的结果是对指针转换的引用,但这是不允许的†。

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


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

于 2013-09-05T13:59:27.530 回答
3

做就是了

alignas(16) float mas[SIZE];

std::aligned_storage是来自boost.

于 2013-09-05T18:55:02.153 回答