我正在尝试从 std::vector
的数据构建 std::array
. 我目前这样做了:
#include <vector>
#include <array>
int main(void)
{
std::vector<int> vec{{1, 2, 3, 4, 5}};
std::array<int, 5> arr{static_cast<int [5]>(vec.data())};
(void)arr;
return 0;
}
但是gcc不接受这个演员:
错误:从'int *'类型的static_cast无效到类型'int [5]'
我以为数组可以用作指针,为什么我们不能这样做?
编辑:这不是Copy std::vector into std::array的副本,因为我的问题是 initialization (构造) std::array
;不要复制到它 .
编辑:我这样做了:
#include <vector>
#include <array>
int main(void)
{
std::vector<int> vec{{1, 2, 3, 4, 5}};
int *a(vec.data());
std::array<int, 5> arr{*reinterpret_cast<int (*)[5]>(&a)};
(void)arr;
return 0;
}
但阵列没有初始化...... gcc说:
error:必须使用大括号括起初始化程序初始化数组
4 回答
std::array
是聚合类型;它没有任何用户定义的构造函数 . 它的单个数据成员是一个数组,不能在函数或构造函数调用中传递;通过值传递的数组衰减到指向其第一个元素的指针,以及array passed by reference cannot be used to initialize an array data member .这意味着一个
array<T, N>
可以通过另一array<T, N>
或高达在{}
-enclosed列表N
类型的T
值的文字序列仅初始化 .从C 17开始,您将能够使用库函数to_array将对数组的引用转换为
std::array
:正如您在Possible implementation部分中看到的,这是在内部分别初始化每个元素:
您可以使用递归模板来实现与您想要的类似的东西 . 诀窍是使用变量模板中的...运算符将参数列表构造到数组构造函数,该变量模板具有所需的向量元素索引作为其可变参数 . 在实现此目的的下面的实现中,然后在模板中完成数组本身的构造,并且您可以依赖返回值优化来确保不进行复制以将值获取到最终数组中 . 这实现了你从矢量初始化数组的既定目标,虽然它有点人为,并不一定是你真正想做的事情 .
"I thought an array could be used as a pointer so why cannot we do this cast?"
您可以使用数组作为指针,因为它们是"decay" . 见"What is array decaying?"
但事实恰恰相反 . (还有对不同大小的数组进行类型检查 . )
虽然
static_cast
可用于反转某些隐式转换,但这只是't one of them. It'明确地excluded from the list:所以这可能会让你想知道如何将指针转换为数组类型 . 你不能,因为"Arrays are second-class citizens in C (and thus in C++)."
reinterpret_cast
也不会工作 .(如果您尝试使用像
(int [5])(vec.data())
这样的C风格的演员表,您可能会获得更明确的消息 ISO C++ forbids casting to an array type 'int [5]' . )所以's just how the language implementation falls out. And here what you'正在尝试初始化一个
std::array
,其存在的理由只是wrap a C array:因此,当涉及到初始化表单时,它对于C数组来说并不是一样的 . 如果你手中有一个整数指针并想从该指针初始化一个
int arr[5] = ...
,那你也同样不走运 . 你必须复制它 .在这种情况下,可以用...完成
Copy std::vector into std::array
来自cpp array参考:
您应该使用默认初始化构造它,然后将矢量内容复制到它 .