如何实现以下目标:
std::vector<int> vec = { 1, 2, 3 };
const int N = vec.size();
// Now create NxN 2D array.
首先,我知道我可以用new
来完成它,但是我必须记住以后删除它,如果可能的话,我不想处理内存的分配问题。
其次,我不能声明堆栈上的2D数组,因为N不是(在本例中也不能)常量表达式。(无论如何,我使用的是VS2013,它不支持constexpr
。)
第三,我不能(或者可能不知道如何)使用std::array
,因为显然“局部变量不能用作非类型参数”。(我从VS2013编译对话中复制-粘贴了这一点,但对这一点了解甚少)。
第四,我正在考虑使用unique_ptr
。问题是,我知道如何对一维数组使用unique_ptr
,比如std::unique_ptr<int> arr{ new int[N] }
,但不知道如何对2D数组这样做。
最后,我知道我总是可以围绕堆上创建的C样式数组编写自己的薄包装器,也可以编写自己的2D数组类。但是,在C++ (C++11)中是否有一种本地或标准库方法来实现这一点呢?
发布于 2015-04-06 19:21:49
std::experimental::array_view
是一个在填充缓冲区上具有动态大小界限的n维数组的视图.
因此,一种方法是创建一个连续缓冲区(例如,一个std::vector<T>
或一个std::unique_ptr<T[]>
),然后将一个array_view<T,2>
封装在它周围。
通过视图对象进行访问,它将具有从数组中期望的操作。存储与查看存储的方式是分开管理的。
为1和2维情况编写此array_view
的简化版本并不困难。但是结果是,您的代码具有很高的性能,并且在使用时非常清晰。胶水代码(对于array_view
)可能有点棘手,但是一旦测试过之后,它应该是可靠的:类似的构造可能很快就会添加到std
中,这意味着它不会在很长一段时间内变得模糊不清。
在我的经验中,一旦我有了一个可靠的array_view
类型,我就会使用它代替以前使用std::vector
传递数据束的地方(效率不高)。
如果您想编写自己的代码,我将跳过有关界和索引的部分,只需实现切片--在二维[]
上array_view
返回第1维array_view
,而在第1维array_view
上实现[]
返回T&
。
发布于 2015-04-06 15:11:31
我建议你给它写一堂课。
下面的示例: 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-08 00:47:21
这样做的标准库方法是:
std::vector< std::vector<int> > vec2d (vec.size(), vec);
它将使用来自vec
的值初始化每一行。如果你不想这样做,那就放弃最后的论点。
https://stackoverflow.com/questions/29472890
复制相似问题