将 C cstyle 数组视为 std::array

Treat C cstyle array as std::array

本文关键字:std array cstyle 数组      更新时间:2023-10-16

是否有任何安全且符合标准的方法可以将 C 样式数组视为 std::array,而无需将数据复制到新的 std::array 中?

这显然不能编译,但这是我想要的效果(我的实际用途更复杂,但这个简短的示例应该显示我想做什么)。我想reinterpret_cast会"工作",但可能不安全?

#include <array>
int main()
{
    int data[] = {1, 2, 3, 4, 5};
    // This next line is the important one, treating an existing array as a std::array
    std::array<int, 5>& a = data;
}

感觉应该是可能的,因为数据应该以相同的方式存储。

编辑:为了清楚起见,我不想清除新的 std::array,我想将现有数据称为一个。

如本文所述如果 T 是 POD,std::array<T,> 是否保证是 POD?

std::array<int, N>是 POD,因此是标准布局。据我了解标准布局要求,这意味着指向对象的指针与指向第一个成员的指针相同。由于 std::array 没有私有/受保护的成员(根据 http://en.cppreference.com/w/cpp/container/array),这应该与包装数组中的第一个元素一致。因此类似

reinterpret_cast< std::array<int, 5>* >( &data )

在我看来,保证按标准工作。不过,我不得不承认,我有时很难解释标准语言,所以如果我错了,请纠正我。

问候克拉斯

您可以使用

reinterpret_cast,但请注意,这是一个丑陋的肮脏黑客,您不应该在实际发布代码中做这样的事情:

std::array<int, 5> &a = reinterpret_cast<std::array<int, 5>&>(data);

如果 std::array 的内部实现发生变化(例如,将在 STL 的调试版本中添加一些额外的字段以执行一些运行时检查),则可能会出现问题。然后,此代码将在没有任何信息性消息的情况下开始崩溃(因为它基于一个隐含的假设,即 std::array 对象和 C 数组具有相同的内存布局)。

如果你决定去丑陋的肮脏黑客,至少添加一个编译时大小检查:

    C_ASSERT(sizeof(a) == sizeof(data));

如果 std::array<> 的大小停止与 C 数组的大小匹配(由于 STL 实现中的一些更改),这将产生错误。

你不能那样做。std::array是一个聚合,并保存自己的数据块(而不是指向可以轻松重新分配的数据块的指针)。因此,无法避免所有元素的副本。在 C++11 中,这一点尤其重要,因为数组的数据无法移动,因此没有有效的std::swap函数。