Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::array iterator range without template?

With C arrays, it is fairly easy to write code that takes arrays of any size:

void func( T* itBegin, T* itEnd );

void main() {
    T arr1[1];
    func( std::begin(arr1), std::end(arr1) );
    T arr2[2];
    func( std::begin(arr2), std::end(arr2) );
}

How can I do that with std::arrays?

void func( ??? itBegin, ??? itEnd );

void main() {
    std::array<T,1> arr1;
    func( std::begin(arr1), std::end(arr1) );
    std::array<T,2> arr2;
    func( std::begin(arr2), std::end(arr2) );
}

The problem is that, in MSVC 2010, std::array<T,N>::iterator is different for different N. Is this a bug in MSVC 2010? If not, what is the rationale of this design? Yes, I could get pointers from the std::array and pass them instead of iterators, but isn't that unnecessarily ugly?

BTW, boost::array<T,N>::iterator are the same for all N.

like image 927
Arno Avatar asked Sep 24 '26 19:09

Arno


2 Answers

template <class I>
void func(I begin, I end)
{
    for (auto x = begin; x != end; ++x)
        something_with(*x);
}

Define them genericly as a type parameter, and then just use them as if they were pointers. Anything that behaves pointer-like will compile, things that don't, won't.

Pointer-like things include normal pointers, as well as standard library iterators, and anything else that defines operator=, operator* and operator++.

Doing it this way and as you will only ever use matching pairs of begin/end iterator ranges from the same array<N>, then it doesn't matter if array<N>::iterator is a different type to array<M>::iterator.

like image 130
Andrew Tomazos Avatar answered Sep 26 '26 08:09

Andrew Tomazos


As far as I can tell, the standard doesn't require that different sized std::array have the same type of iterator; having a different type for std::array<int, 1> and std::array<int, 2> seems legal (although one might have some opinions with regards to the quality of the implementation).

If this is a problem, you can either use a C style array, or use pointers:

func( &arr1[0], &arr1[0] + arr1.size() );

Neither solution is ideal, but they're the best I can offer.

like image 40
James Kanze Avatar answered Sep 26 '26 09:09

James Kanze



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!