【问题标题】:Return std::array of unknown size返回未知大小的 std::array
【发布时间】:2018-05-26 18:17:16
【问题描述】:

我想从我的函数中返回一个多维 std::array。返回数组的大小应由输入参数的大小决定。 比如:

std::array<std::array<unsigned int, n>, n> foo(std::vector<int> vec){
    unsigned int n = vec.size;
    std::array<std::array<unsigned int, n>, n> result;
    return result;
}

如果没有烦人的额外模板参数来解决这个问题会很好。 std::vector 而不是 std::array 似乎不像 std::array (没有显式初始化)那样用 n (未确定的)项目初始化。这怎么可能?谢谢!

【问题讨论】:

  • std::array 的大小必须在编译时知道。这就是尺寸模板化的原因
  • 为什么需要使用 std::array 作为返回类型而不是 std::vector?
  • @ F. Salido:对于类似 C 风格的数组,您可以执行以下操作: int[] foo() { // ... @N. Butterworth:如果我使用 std::vector,我将不得不使用嵌套的 for 循环使用 n^2 个元素初始化完整的对象——我努力省略这一点。 @乔治;如果没有比您迄今为止最好的解决方案更好的解决方案,我希望将它们视为能够将其标记为最佳解决方案的答案:-)
  • @user7427029 int[] foo() 不会编译,int foo()[] 也是如此。
  • @HolyBlackCat 我相信这是一个扩展.. 组织和返回编译时未知大小的多维数组的唯一方法是裸指针,或者是裸指针的包装类指针。向量可以充当替换,重新定义的迭代器可以允许模拟多维的技巧。

标签: c++ arrays c++11 multidimensional-array


【解决方案1】:

您需要知道的第一件事是std::array 的大小在编译时是固定的,就像来自 cppreference sais 的 documentation

std::array 是一个封装固定大小数组的容器。

此容器是一个聚合类型,其语义与 将 C 样式数组 T[N] 作为其唯一非静态数据的结构 会员。

如果n 来自std::cin 或来自命令行参数(或编译时以外的任何类型的输入),则编译器无法推断类型,因此会抛出错误。

最明智的做法是使用std::vector,您可以这样做:

std::vector<std::vector<unsigned int>> foo(std::vector<int> vec){
    unsigned int n = vec.size();
    std::vector<std::vector<unsigned int>> result(n, std::vector<unsigned int>(n));
    return result;
}

只需使用向量的大小构造函数初始化每个向量。

【讨论】:

  • 我觉得在这种情况下 RVO 是不可能的
  • @Swift 好吧,如果您不想创建新副本,您可以随时强制移动,这没什么大不了的。
【解决方案2】:

您可以使用其 c'tor 创建一个 n 大小的 std::vectorn 大小的 std::vector s,即:

std::vector&lt;std::vector&lt;unsigned int&gt;&gt; result(n, std::vector&lt;unsigned int&gt;(n, 0));

注意:根据cppreference.com,上面std::vector s c'tor 示例中使用的第二个参数是要创建的每个项目的值:c'tor 签名:

vector( size_type count, const T&amp; value, const Allocator&amp; alloc = Allocator());.

【讨论】:

  • 这是可能的,但它是分配成本的噩梦......或者对于尝试使用这种存储结构的多线程的任何人来说都是噩梦
  • @Swift “有可能,但这是分配成本的噩梦” 为什么?而且我怀疑多线程是否相关,但为什么使用std::vector&lt;std::vector&lt;&gt;&gt;(尤其是在小程序中)会成为问题?
  • C++ 是一种可以将复杂代码隐藏在简单结构后面的语言 该类型本质上是一个行数不均匀的数组,因为每一个“行”都由向量表示,并且可以独立改变其大小。但它不是 python 的 numty 的模拟。如果不将所有数据复制到另一个存储,就无法将其表示为 2D 数组。如果 OP ever 需要做后者(使用大量 API(例如 OpenGL)或与 python 或其他语言接口的非常常见的问题),他能做到的唯一有效方法是制作一个包装类围绕一维向量。
【解决方案3】:

尝试使用Boost.MultiArray。它允许您创建具有任意内容类型的内容的多维数组。我已经使用了它(更具体的 boost::multi_array_ref 部分)并且效果很好。一个重要的特性是能够创建数组views(以及基于视图的切片)。

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    相关资源
    最近更新 更多