Yes.
You can remap the way you access the elements without needing to copy them. You can create a "view" class to achieve that:
template<typename T>
class two_dee_view
{
public:
two_dee_view(std::vector<T>& v, std::size_t row, std::size_t col)
: v(v), stride(col) { if(v.size() < row * col) v.resize(row * col); }
T& operator()(std::size_t row, std::size_t col)
{ return v[(row * stride) + col]; }
T const& operator()(std::size_t row, std::size_t col) const
{ return v[(row * stride) + col]; }
std::size_t col_size() const { return stride; }
std::size_t row_size() const { return v.size() / stride; }
private:
std::vector<T>& v;
std::size_t stride;
};
int main()
{
std::vector<double> v {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
two_dee_view<double> v2d(v, 2, 3);
for(auto row = 0U; row < v2d.row_size(); ++row)
for(auto col = 0U; col < v2d.col_size(); ++col)
std::cout << row << ", " << col << ": " << v2d(row, col) << '\n';
}
Output:
0, 0: 1
0, 1: 2
0, 2: 3
1, 0: 4
1, 1: 5
1, 2: 6
The class simply maintains a reference to the std::vector
you pass in to the constructor. You should only use the two_dee_view
as long as the original std::vector
lives but no longer.