You cannot do that directly.
I would suggest to write a little class/struct that would wrap your 2D array conveniently. Here I use std::vector
instead of int *arr
and you do not have to care about memory management. The following code presents 3 possibles methods :
Method 1 (recommended) : accessing via mat(i,j)
The operator()(size_t i, size_t j)
is called function call operator.
template<typename T>
struct Matrix
{
Matrix(const std::vector<T>& d, size_t s) : Matrix(d, s, s) {}
Matrix(const std::vector<T>& d, size_t c, size_t r) : data_(d), cols_(c), rows_(r) {}
std::vector<T> data_;
size_t cols_;
size_t rows_;
const T& operator()(size_t i, size_t j) const { return data_[i * cols_ + j]; }
T& operator()(size_t i, size_t j) { return data_[i * cols_ + j]; }
// and you can add other convenient methods
};
Use it like this :
Matrix<int> mat({1, 2, 3, 4, 5, 6, 7, 8, 9}, 3, 3); // a 3x3 matrix
std::cout << mat(1,2) << std::endl;
Live code
If you know the size at compile time then you can use std::array
and change your struct accordingly :
template<typename T, size_t Cols, size_t Rows> struct Matrix
{
std::array<T, Cols * Rows> data_;
// etc...
Method 2 : accessing via mat[{i,j}]
Using the array subscript operator only takes one argument so you can change/add the following operators to your class :
const T& operator[](const std::array<size_t,2>& a) const { return data_[a[0] * cols_ + a[1]]; }
T& operator[](const std::array<size_t,2>& a) { return data_[a[0] * cols_ + a[1]]; }
which can be called like this :
std::cout << mat[{1,2}] << std::endl;
Note that this method is useful when you work on several dimensions (you do not have to write several operator()(size_t i, size_t j, size_t k, etc...)
Method 3 (not recommended) : accessing via mat[Idx(i),Idx(j)]
You can take two arguments using the array subscript operator but you have to overload the comma operator which is not possible between two built in types... So accessing directly via mat[i,j]
is not possible (Thanks leemes' comment for pointing that out).
However you can create your own type and overload it. Here an example (put it before your Matrix class definition) :
struct Idx
{
Idx(size_t ii) : i(ii) {}
size_t i;
operator size_t() const { return i; } // implicit user-defined conversion
};
std::array<size_t, 2> operator , (Idx i1, Idx i2)
{
return { i1, i2 };
}
// etc...
// and we do not have to add Matrix operators since we reused the one from Method 2
Use it like this :
std::cout << mat[Idx(1),Idx(2)] << std::endl;
which is not that elegant...
Complete and final live code