4

I want to copy an array using range for. Is it possible?

Something like (obviously not working)

unsigned arr[15] = {};
unsigned arr2[15];

for (auto i : arr, auto &j : arr2)
    j = i;

Or are there some other tricks to avoid operating the size of arrays, if I know for sure they are of the same lenght?

UPD I really like the @PavelDavydov solution. But could anyone please offer a standard lib only solution. C++11 contains pairs and tuples too.

for (auto pair : std::make_tuple(&arr, &arr2));
NuPagadi
  • 1,390
  • 9
  • 30

4 Answers4

10
#include <boost/range/combine.hpp>

for (const auto& pair : boost::combine(arr, arr2)) {
  cout << get<0>(pair) << endl;
}

Update: ok, if you want to do it without boost, you can implement a higher order function for that.

template <class T, unsigned long FirstLen, unsigned long SecondLen, class Pred> 
typename std::enable_if<FirstLen == SecondLen, void>::type loop_two(T (&first)[FirstLen], T (&second)[SecondLen], Pred pred) {
  for (unsigned long len = 0; len < FirstLen; ++len) {
    pred(first[len], second[len]);  
  }
}

and than use it like this:

loop_two(arr, arr1, [] (unsigned a, unsigned b) {
  cout << a << endl;
});
Pavel Davydov
  • 3,079
  • 1
  • 27
  • 41
5
#include <iterator>
//.. 

unsigned arr[15] = {};
unsigned arr2[15];

//.. 

auto it = std::begin( arr2 );

for ( unsigned x : arr ) *it++ = x;

It would be better to use standard algorithm std::copy because its name says about your intention.

#include <algorithm>
#include <iterator>
//...

std::copy( std::begin( arr ), std::end( arr ), std::begin( arr2 ) );

For arrays of arithmetic types you can use also C function memcpy

#include <cstring>

...

std::memcpy( arr2, arr, std::extent<decltype(arr)>::value * sizeof( unsigned ) );
Vlad from Moscow
  • 265,791
  • 20
  • 170
  • 303
3

There are several good answers already, another is to use a zip iterator such as https://gitlab.com/redistd/redistd/blob/master/include/redi/zip.h (which currently depends on Boost.Tuple)

#include <redi/zip.h>

int main()
{
  unsigned arr[15] = {};
  unsigned arr2[15];

  for (auto i : redi::zip(arr, arr2))
    i.get<1>() = i.get<0>();
}
Jonathan Wakely
  • 160,213
  • 23
  • 318
  • 501
1

It's possible. I suggest use std::begin and std::end function. For example:

for(auto it1 = std::begin(arr), it2 = std::begin(arr2); it1 != std::end(arr); ++it1,++it2)
 *it2 = *it1;

However, you can use std:array or std::vector instead 'normal' arrays. It's C++11!

Tacet
  • 1,401
  • 2
  • 17
  • 30