为带参数的函数转换 boost::array<float, 12> (const float (&arr)[12])

Cast boost::array<float, 12> for function with argument (const float (&arr)[12])

我有一个 boost::array<float, 12>,我想将其用作函数的输入,其签名是:

Foo(const float(&arr)[12])

我已经尝试通过 .data() 从 boost::array 获取数据元素,但是这个 returns 是一个浮点指针,不适合我的签名。我可以更改需要的函数签名,但不想这样做。想法?

将编译以下代码:

#include <array>

void f(int (&arr)[4])
{
}

int main() 
{
    std::array<int, 4> arr = {1, 2, 3, 4};
    f(*reinterpret_cast<int (*)[4]>(arr.data()));
    return 0;
}

诀窍是使用 reinterpret_castarr.data() 返回的 int* 转换为 "pointer to an array"(即 int (*)[4])。然后,您取消引用它以获得该数组的 "reference"。

编辑:最好使用类似下面的模板,以确保将指针转换为适当的数组类型。

template<class T, std::size_t N>
T (&as_simple_array(std::array<T, N>& arr))[N] {
    return *reinterpret_cast<T (*)[N]>(arr.data());
}

然后您可以像这样使用它:

f(as_simple_array(arr));

synopsis 表示实际的数组名为 elems,所以这应该有效:

Foo(my_array.elems);

从这里不清楚该成员是否保证如此命名,或者它是否像标准中的某些成员一样 "exposition only"。无论如何,以下应该有效,但它很丑陋:

Foo(reinterpret_cast<const float (&)[12]>(my_array[0]));

这是在 C++14 中明确定义的。 引用的 reinterpret_cast 与对应的 reinterpret_cast 指针具有相同的语义([ expr.reinterpret.cast]/11),

*reinterpret_cast<const float (*)[12]>(&my_array[0])

这个重新解释的转换又等同于双重 static_cast ([expr.reinterpret.cast]/7):

static_cast<const float (*)[12]>(static_cast<const void*>(&my_array[0]))

cvvoid的转换保证给出指向对象第一个字节的指针([conv.ptr]/2)。只要地址与目标类型 ([expr.static.cast]/13) 的对象适当对齐,后续到 const float (*)[12] 的转换也保证提供指向相同字节的指针,这必须是因为它最初是一个数组的地址。