Finally, C++23 allows overload for the subscript operator [] to be multi-dimensional.

Before that, we normally either use:

  1. vector of vector to form a matrix, and access it as mat[i][j]
  2. a class containing a big 1-d vector, but behaves as 2-d by overloading the operator (), e.g., mat(i,j)

Now, with C++23, we advance the second option (which offers efficient memory access) with better indexing approaching as follow:

template <typename T, size_t R, size_t C>
struct matrix
{
  T& operator[](size_t const r, size_t const c) noexcept
  {
    return data_[r * C + c];
  }
  T const& operator[](size_t const r, size_t const c) const noexcept
  {
    return data_[r * C + c];
  }
  static constexpr size_t Rows    = R;
  static constexpr size_t Columns = C;

  private:
  std::array<T, R * C> data_;
};

int main()
{
  matrix<int, 3, 2> m;
  for(size_t i = 0; i < m.Rows; ++i)
  {
    for(size_t j = 0; j < m.Columns; ++j)
    {
      m[i, j] = i * m.Columns + (j + 1);
    }
  }

  for(size_t i = 0; i < m.Rows; ++i)
  {
    for(size_t j = 0; j < m.Columns; ++j)
    {
      std::cout << m[i, j] << ' ';
    }

    std::cout << '\n';
  }
}