2

我如何实现以下目标:

std::vector<int> vec = { 1, 2, 3 };
const int N = vec.size();
// Now create NxN 2D array.

首先,我知道我可以做到new但我必须记得稍后删除它,如果可能的话,我宁愿不必处理内存释放。

其次,我不能在堆栈上声明二维数组,因为 N 不是(在这种情况下也不能是)常量表达式。(无论如何我使用的是 VS2013,它不支持constexpr。)

第三,我不能(或者可能不知道如何)使用std::array,因为显然“局部变量不能用作非类型参数”。(我从 VS2013 编译对话中复制粘贴了这个,对这一点知之甚少)。

第四,我正在考虑使用unique_ptr. 问题是,我知道怎么用unique_ptr用于一维数组,例如std::unique_ptr<int> arr{ new int[N] },但不知道如何为二维数组执行此操作。

最后,我知道我总是可以围绕始终在堆上创建的 C 样式数组编写自己的瘦包装器,或者编写自己的 2D 数组类。但是在 C++ (C++11) 中是否有本机或标准库方式来执行此操作?

4

4 回答 4

2

std::experimental::array_view是在打包缓冲区上具有动态大小界限的 n 维数组的视图。

因此,一种方法是创建一个连续的缓冲区(例如 astd::vector<T>或 a std::unique_ptr<T[]>,然后将 an 包裹array_view<T,2>起来。

通过视图对象访问,它将具有您应该从数组中获得的操作。存储与查看存储的方式分开管理。

为 1 维和 2 维情况编写一个简化版本array_view并不难。但结果是您的代码是高性能的,并且在使用时非常清晰。胶水代码 (for array_view) 可能有点棘手,但一旦测试它应该是可靠的:并且类似的构造将std很快被添加到的可能性意味着它不会长期保持晦涩难懂。

根据我的经验,一旦我有了一个可靠的array_view类型,我就会将它用作我过去(低效地)std::vector用来传递数据包的地方的替代品。

如果你想自己写,我会跳过关于边界和索引的部分,只执行切片——[]在第 2 维array_view返回第 1 维array_view[]在第 1 维array_view返回 a T&

于 2015-04-06T19:21:49.697 回答
1

我建议你为它写一个类。

下面的示例: set() 在设置值之前调整它的大小。运算符 [] 返回该行的列向量,因此当您应用运算符 [] 时,它会返回所需的值。如果您发现任何问题,请告诉我;)。

class 2DVector {
 std::vector<std::vector<int>> m_items;

 void set(int value, size_t row, size_t column) {
   for (int i=m_items.size(); i<=row; i++) {
      m_items.push_back(std::vector<int>());
   }
   for (int i=0; i<m_items.size(); i++) {
      for (int j=m_items[i].size(); j<=column; j++) {
      m_items[i].push_back(0);
   }
   m_items[row][column] = value;
 }

 std::vector<int> &operator [](size_t index) {
   return m_items[index];
 }
}

用法:

2DVector v;
v.set(200, 0, 0);
v.set(201, 1, 0);
std::cout << v[0][0]; //prints 200
std::cout << v[1][0]; //prints 201
于 2015-04-06T15:11:31.963 回答
0

这样做的标准库方法是:

std::vector< std::vector<int> > vec2d (vec.size(), vec);

这将使用来自 的值初始化每一行vec。如果您不想这样做,那么请忽略最后一个参数。

于 2015-04-08T00:47:21.143 回答
-1

用一维数组模拟一个二维数组怎么样?就像openCV2所做的那样

伪代码

class 2DVector {         
 void set(int value, size_t row, size_t column) {
   m_items[row * column_size + column];
 }

 int &operator [](size_t row, size_t column) {
   return m_items[row * column_size + column];
 }

 private:
   std::vector<int> m_items;
}

或者只是使用 boost::multi_array(不确定性能是否适合您的情况)。

于 2015-04-07T06:23:47.133 回答