简体   繁体   中英

Rcpp Copy a vector to a vector

I am new to Rcpp and C++ coding in general, so forgive me for asking basic questions. The cpp part of the code is

// test.cpp

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void testRun() {
   IntegerVector Grp1 = IntegerVector::create(1,2,3,4);
   IntegerVector Grp2 = IntegerVector::create(3,4,5,6);

   Rf_PrintValue(Grp1);
   Grp1 = Grp2;
   Rf_PrintValue(Grp1);
   Grp2[3] = Grp2[3]+1;
   Rf_PrintValue(Grp1);
}

and when I run testrun(), I get the output

> Rcpp::sourceCpp('test.cpp')
> testRun()
[1] 1 2 3 4
[1] 3 4 5 6
[1] 3 4 5 7

When I assign Gr2 to Gr1 in Gr1 = Gr2 , changing elements in Gr2 after the assignment changes the values in Gr1 as well. Is there a function for IntegerVectors that could do something like Gr1 = copy of Gr2 or should I be using a loop to do that.

Thanks a lot!

As hinted in the comment, you could use

Grp1 = clone(Grp2) ;

but this will create a new R object that then get assigned to Grp1 , so you pay for some memory allocation and you discard some memory that could have been used, ie more work for the garbage collector down the line.

You could also just reuse the existing memory from Grp1 with std::copy

std::copy( Grp2.begin(), Grp2.end(), Grp1.begin() ) ;

Another way that is perhaps over the top is to use sapply . Something like this:

auto identity = [](double x){ return x; } ;
Grp1 = sapply( Grp2, identity );

But given Rcpp does not sapply over lambdas , you'd probably have to define identity outside your function for this approach to be useable.

inline double identity(double x){ 
    return x ;
}

FWIW, in Rcpp14 or Rcpp11 , you could simply do:

Grp1 = import(Grp2) ;

What is currently happening is a very common error with pointers. Grp1 and Grp2 are pointers, so setting one equal to the other means that they point to the same array (and any changes to one array will affect the other). One solution would be to use a iterator to copy all values over one at a time. This would be done by emptying one IntegerVector by popping all values and then pushing all elements from the other IntegerVector into the emptied IntegerVector.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM