I want to use std::copy to copy an existing array of structures to new one. A regular option is fine with '''local_copy()'''. I want to know the procedure to use std::copy for such case described below -
I tried the code and get following error at compile time
#include <iostream>
class BigClass{
public:
struct Astruct{
double x[2], v[2];
int rank;
}one_struct;
};
void allocate(struct BigClass::Astruct& one_struct, int i)
{
one_struct.x[0] = 1.1;
one_struct.x[1] = 1.2;
one_struct.v[0] = 2.1;
one_struct.v[1] = 2.2;
one_struct.rank = i;
}
void local_copy(struct BigClass::Astruct& dest, struct BigClass::Astruct& source)
{
dest.x[0] = source.x[0];
dest.x[1] = source.x[1];
dest.v[0] = source.v[0];
dest.v[1] = source.v[1];
dest.rank = source.rank;
}
void print(struct BigClass::Astruct one_struct)
{
std::cout << one_struct.rank << " " << one_struct.x[0] << " " << one_struct.x[1] << " " << one_struct.v[0] << " " << one_struct.v[1] << "\n";
}
int main(int argc, char *argv[]) {
int size = 10;
struct BigClass::Astruct BCobj[size];
for(int i = 0; i < size; i++) allocate(BCobj[i], i);
for(int i = 0; i < size; i++) print(BCobj[i]);
struct BigClass::Astruct second_BCobj[size];
//for(int i = 0; i < size; i++) local_copy(second_BCobj[i], BCobj[i]); // this works
for(int i = 0; i < size; i++) std::copy(BCobj[i+1], BCobj[i], second_BCobj[i]); // not working
for(int i = 0; i < size; i++) print(BCobj[i]);
}
The compile time error is following -
/usr/include/c++/7/bits/stl_algobase.h:377:57: error: no type named ‘value_type’ in ‘struct std::iterator_traits<BigClass::Astruct>’
typedef typename iterator_traits<_II>::value_type _ValueTypeI;
^~~~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:378:57: error: no type named ‘value_type’ in ‘struct std::iterator_traits<BigClass::Astruct>’
typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
^~~~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:379:64: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<BigClass::Astruct>’
typedef typename iterator_traits<_II>::iterator_category _Category;
^~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:383:9: error: no type named ‘value_type’ in ‘struct std::iterator_traits<BigClass::Astruct>’
const bool __simple = (__is_trivial(_ValueTypeI)
~~~~~~~~~~~~~~~~~~~~~~~~~~
&& __is_pointer<_II>::__value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
&& __is_pointer<_OI>::__value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
&& __are_same<_ValueTypeI, _ValueTypeO>::__value);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:386:44: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<BigClass::Astruct>’
return std::__copy_move<_IsMove, __simple,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_Category>::__copy_m(__first, __last, __result);
~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
Some examples for vectors and int datatypes are available. Could anyone elaborate the appropriate sequence for std::copy for this kind of code structure? Thanks.
std::copy
is used instead of for
loop, not with one.
std::copy(BCobj, BCobj + size, second_BCobj);
is essentially the same as
for(int i = 0; i < size; ++i) {
second_BCobj[i] = BCobj[i];
}
Also, don't forget to #include <algorithm>
for std::copy
Explanation of arguments for std::copy
:
std::copy
takes as arguments 2 arguments of type matching InputIterator requirements and single argument of type OutputIteretor. Fortunately, pointers match these requirements, so we can use them directly. And because array name is interpreted as a pointer to its first element, we can pass it directly as argument to std::sort
Better version as suggested by Chef Gladiator:
std::copy(std::begin(BCobj), std::end(BCobj), std::begin(second_BCobj))