【问题标题】:compiler error with C++ std::vector of arrayC++ std::vector 数组的编译器错误
【发布时间】:2012-08-29 19:02:39
【问题描述】:

以下代码无法使用 gcc 4.7.0 编译(使用 std=c++11 -O3)

int n;
std::vector< int[4] > A;
A.resize(n);

错误信息是长度,但最终

functional cast to array type ‘_ValueType {aka int[4]}‘

这是正确的吗?还是应该编译?更重要的是,如何避免这个问题? (没有定义一个新的结构来保存int[4]

编辑:

如何解决C++98的问题?

【问题讨论】:

  • 只需使用std::vector&lt;std::array&lt;int, 4&gt;&gt; A (n);
  • @chris:假设您有 std::array 可用。
  • @chris 好的,但是你在 C++ 98 中做什么?
  • 您已经淘汰了任何具有不合理要求的解决方案。
  • @chris std::array 是一个围绕内置 c++ 数组的薄包装器,如果您不需要它,您可以创建一个包含长度为 4 数组的结构。我知道问题说不要,但我经常这样做。如果你想要索引,你可以重载operator []

标签: c++ arrays stdvector


【解决方案1】:

您不能将数组存储在向量或任何其他容器中。要存储在容器中的元素的类型(称为容器的值类型)必须是可复制构造和可赋值的。数组都不是。

但是,您可以使用数组类模板,例如 Boost、TR1 和 C++0x 提供的模板:

std::vector<std::array<type, size> >

(您需要将 std::array 替换为 std::tr1::array 以使用 C++ TR1 中包含的模板,或 boost::array 以使用来自Boost libraries 的模板。或者,您可以自己写;这很简单。)

@source 作者:詹姆斯·麦克内利斯

所以代码看起来像:

int n;
std::vector<std::array<int,3>> A;
A.resize(n);

【讨论】:

  • 这根本不符合 OP 的要求。所做的只是创建一个初始长度为 4 的整数向量,而不是 4 长度整数数组的向量。
  • 对不起,我理解错了,但是我已经编辑了我的答案。希望对你有帮助
  • @R.MartinhoFernandes:推断什么?我的第一条评论是指旧版本的 sshekhar 的答案,这是不正确的。他编辑了答案,现在它实际上回答了这个问题,所以我删除了我给它的反对票。
  • 注意,在 C++11 中,要求不再是可复制分配和可复制构造,而是根据被调用的函数而有所不同。特别是,他调用的方法需要默认构造函数。
  • @DaveS 如果这是真的(这似乎是合理的,因为在 C++11 中,std::vector 有两个版本的 resize(),一个只有一个 size_type 的参数,一个有第二个value_type const&amp;) 的参数,那么我的代码应该可以工作,因为 std::is_default_constructible&lt;int[4]&gt;::value == true
【解决方案2】:

没有定义一个新的结构来保存 int[4]

不可能。您必须定义或查找结构(std::arraystd::tr1::arrayboost::array)。否则,此代码将永远无法编译。

【讨论】:

  • 为什么?是否违反了std::vector 的明确要求?
  • @Walter:“为什么?”因为 C++ 编程语言规范是这么说的。
  • @NicolBolas 具体是哪个规范?
  • @DeadMG 此评论几乎可以被标记为不具建设性/冒犯性。标准 规范组成,但不是一个规范。请不要制作无用的 cmets。
  • @Walter:向量元素必须是可分配的,即您必须仅使用可分配的类型 T 实例化 vector&lt;T&gt;int[4] 不是。您不能将一个 int[4] 分配给另一个。您可以将一个 array&lt;int,4&gt; 分配给另一个(当然,它会反复进行成员分配)。
【解决方案3】:

见 23.1/3:

存储在这些组件中的对象类型必须满足 CopyConstructible 类型 (20.1.3) 的要求,以及附加的 可分配类型的要求。

因此在 C++03 vector 中要求包含的项目是可复制构造的,而 C 样式的数组则不是。错误消息是正确的,代码应该无法编译。只需在 C++11 中使用向量的向量、struct 来包装数组或 std::array 的向量。

请注意,我相信可复制构造的限制在 C++11 中已在容器范围内解除,我不确定是否/如何将 C 样式的数组存储在一个数组中,或者是否更明确地禁止它。

【讨论】:

  • 我不这么认为。在 C++11 中,std::vector::resize(size_type) 不采用第二个参数(有一个版本采用第二个参数)并且应该使用默认构造函数,而不是复制构造函数。
  • @Walter OP 说 C++98(可能也在 C++03 中)而不是 C++11。
猜你喜欢
  • 2015-01-04
  • 2022-12-07
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 2014-12-27
相关资源
最近更新 更多