是否有任何安全且符合标准的方法将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,我想将现有数据称为一个。
答案 0 :(得分:21)
正如本文所述 Is std::array<T, S> guaranteed to be POD if T is POD?
std::array<int, N>
是POD,因此是标准布局。据我所知,标准布局要求,这意味着指向对象的指针与指向第一个成员的指针相同。由于std :: array没有私有/受保护成员(根据http://en.cppreference.com/w/cpp/container/array),这应该与包装数组中的第一个元素一致。因此像
reinterpret_cast< std::array<int, 5>* >( &data )
在我看来保证按标准工作。不过,我不得不承认,我有时难以解释标准语言,所以如果我错了,请纠正我。
此致 克拉斯
答案 1 :(得分:10)
你做不到。 std::array
是一个聚合并拥有自己的数据块(而不是指向可以轻松重新分配的数据块的指针)。所以没有办法避免所有元素的副本。在C ++ 11中,这一点特别重要,因为数组的数据无法移动,因此没有高效的std::swap
函数,例如。
答案 2 :(得分:9)
你可以使用 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&lt;&gt;的大小,这将产生错误停止匹配C数组的大小(由于STL实现中的一些更改)。