Chapter 19 Cautions in handling Rcpp objects
19.1 Assigning between vectors
When you assign an object v1
to another object v2
using =
operator (v2 = v1;
), the value of elements of v1
is not copied to v2
but v2
will be an alias to v1
. Thus, if you change the value of some elements in v1
, the change also applied to v2
. You should use clone()
, if you want to avoid coupling between objects (see sample code below).
The sample code presented below shows that the difference of the shallow copy and deep copy when you change value of one of vector after assigning.
NumericVector v1 = {1,2,3}; // create a vector v1
NumericVector v2 = v1; // v1 is assigned to v2 through shallow copy.
NumericVector v3 = clone(v1); // v1 is assigned to v3 through deep copy.
v1[0] = 100; // changing value of a element of v1
// Following output shows that
// the modification of v1 element
// is also applied to v2 but not to v3
Rcout << "v1 = " << v1 << endl; // 100 2 3
Rcout << "v2 = " << v2 << endl; // 100 2 3
Rcout << "v3 = " << v3 << endl; // 1 2 3
As explanation for people who have deeper knowledge of C++, a Rcpp object do not have value of R object (e.g. elements of a vector) itself, but have a pointer to R object. Thus, if you assign object through v2 = v1;
, the value of pointer of v1
is copied to v2
. So, both v1
and v2
would be pointing to the same R object. This is called “shallow copy”. On the other hand, if you assign object through v2 = clone(v1);
, the value of R object that v1
is pointing is copied to v2
as new R object. This is called “deep copy”.
19.2 Data type of numerical index
Maximum number of vector elements is limited to the length of 2^31 - 1 in R <= version 2.0.0 or 32 bit build of R, because int
is used as data type of numerical index. However, long vector is supported after 64 bit build of R 3.0.0. You should use R_xlen_t
as data data type for numerical index or the number of elements to support long vector in your Rcpp code.
19.3 Return type of operator[]
When you access to vector elements using []
or ()
operator, the return type is not Vector
itself but Vector::Proxy
. Thus, it will cause compile error when you pass v[i]
directly to some function, if the function only supports Vector
type. To avoid compile error v[i]
assign to new object or convert it to type T
using as<T>()
.