Title
std::begin() and std::end() do not support multi-dimensional arrays correctly
Status
nad
Section
[iterator.range]
Submitter
Janez Žemva

Created on 2014-11-16.00:00:00 last changed 12 months ago

Messages

Date: 2023-04-15.00:00:00

[ 2023-04-06; LWG reflector poll in November 2021 ]

Changed to Tentatively NAD after 12 votes in favour. Use views::join or mdspan instead.

Date: 2014-11-18.22:25:02

The following code:

#include <algorithm>
#include <iterator>
#include <iostream>
#include <cassert>

int main() 
{
  int a[2][3][4] = { { { 1,  2,  3,  4}, { 5,  6,  7,  8}, { 9, 10, 11, 12} },
                     { {13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24} } };
  int b[2][3][4];

  assert(std::distance(std::begin(a), std::end(a)) == 2 * 3 * 4);
  std::copy(std::begin(a), std::end(a), std::begin(b));
  std::copy(std::begin(b), std::end(b), std::ostream_iterator<int>(std::cout, ","));
}

does not compile.

A possible way to remedy this would be to add the following overloads of begin, end, rbegin, and rend to [iterator.range], relying on recursive evaluation:

namespace std {

  template <typename T, size_t M, size_t N>
  constexpr remove_all_extents_t<T>*
  begin(T (&array)[M][N])
  {
    return begin(*array);
  }
  
  template <typename T, size_t M, size_t N>
  constexpr remove_all_extents_t<T>*
  end(T (&array)[M][N])
  {
    return end(array[M - 1]);
  }

  template <typename T, size_t M, size_t N>
  reverse_iterator<remove_all_extents_t<T>*>
  rbegin(T (&array)[M][N])
  {
    return decltype(rbegin(array))(end(array[M - 1]));
  }
  
  template <typename T, size_t M, size_t N>
  reverse_iterator<remove_all_extents_t<T>*>
  rend(T (&array)[M][N])
  {
    return decltype(rend(array))(begin(*array));
  }

}
History
Date User Action Args
2023-04-06 13:59:48adminsetmessages: + msg13510
2023-04-06 13:59:48adminsetstatus: new -> nad
2014-11-16 00:00:00admincreate