数组的 C++ 向量

Posted

技术标签:

【中文标题】数组的 C++ 向量【英文标题】:C++ vector of arrays 【发布时间】:2011-08-27 20:10:49 【问题描述】:

为什么会这样:

std::pair<int, int> p = 1,2;
std::vector<std::pair<int, int>> vp =  1,2, 3,4 ;

但这不是吗?

std::array<int, 2> a = 1,2; // still ok
std::vector<std::array<int, 2>> va =  1,2, 3,4 ;

使用带有-std=c++0x 的g++ 4.5.1,第二行失败并显示:

错误:无法将‘1, 2, 3, 4’ 转换为‘std::vector&lt;std::array&lt;int, 2u&gt; &gt;’

谢谢

【问题讨论】:

你能澄清“失败”吗? (比如给出编译器的错误?) 哪个操作系统?可能是编译器错误 @VJo @mat 添加了更多细节,谢谢! 我实际上怀疑 gcc 4.5.1 在这个问题上并不完全兼容。不幸的是,我不知道可以在这里提供帮助的在线编译器(ideone 使用 4.5.1)。 【参考方案1】:

不幸的是,std::array 没有初始化列表构造函数。事实上,它有 no 用户定义的构造函数——这个“特性”是 C++03 的遗留物,在 C++03 中省略所有用户定义的构造函数是启用 C 样式大括号初始化的唯一方法.恕我直言,这是当前标准中的一个缺陷。

那么为什么在这种情况下内置大括号初始化不起作用呢?让我们看看 std::array 到底是什么样子:

template <typename T, int i> struct array 
    T data[i];
    // ...

好的,这是否意味着我们必须在初始化程序中使用 double 大括号(一对用于array,另一对用于data 成员?

std::array<int, 2> a =  1, 2 ;

C(以及随后的 C++)有一个关于 brace elision 的特殊规则,允许省略内部大括号,除非有歧义。 array利用了这个特性,让我们可以写

std::array<int, 2> a =  1, 2 ;

那么为什么原始帖子中的示例不起作用?因为大括号省略只允许在 C 样式聚合初始化的上下文中使用,而不是在涉及更复杂的事情时,例如用户定义的初始化列表构造函数。

以下应该可以工作,尽管它很丑:

std::vector<std::array<int, 2>> vp =  1,2, 3,4 ;

在我看来,至少在 gcc 4.5 和 gcc 4.6 上没有,这似乎表明存在编译器错误。不过,我并不完全确定。

这个问题有点相关:How do I initialize a member array with an initializer_list?

【讨论】:

我相当怀疑std::array 看起来更像template &lt;typename T, std::size_t i&gt; 是的,你的最后一个例子应该可以工作。除了简单的T t = ... 声明之外,不支持大括号省略是一个有意识且经过讨论的决定。这也是为什么 return ... 不能与 std::array&lt;&gt; 返回类型一起使用的原因。 你的最后一个例子 std::vector<:array>> vp = 1,2, 3,4 ;适用于 gcc 4.7.2【参考方案2】:

这行得通:

std::vector<std::array<int, 2>> va = 
  std::array<int, 2>1,2,
  std::array<int, 2>3,4
;

深入挖掘,似乎 std::pair 有一个构造函数,它接受一个初始化列表,但 std::array 没有:

std::pair<int, int> p (1,2) ;  // OK
std::array<int, 2> a (1,2) ;   // Invalid

但现在我已经超出了我的深度。

【讨论】:

您实际上是在这里为编译器推断大括号初始值设定项列表中元素的类型。我想这就是问题所在,但仍然不知道它是否应该按照标准工作。

以上是关于数组的 C++ 向量的主要内容,如果未能解决你的问题,请参考以下文章

将 C# 数组传递给 C++ 向量

将值从向量分配给动态数组(C++)

C++:如何安全地释放堆分配的向量数组?

将c多维数组转换为多维c++向量

带有浮点索引的 C++ 数组/向量

c++ vector 为啥叫向量