Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
220 views
in Technique[技术] by (71.8m points)

rcpp11 - Declare a variable as a reference in Rcpp

In C++, we can declare a variable as a reference.

int a = 10;
int& b = a;

If we set b=15, a also changes.

I want to do the similar thing in Rcpp.

List X = obj_from_R["X"];
IntegerVector x_i = X[index];
x_i = value;

I want to update an object from R called X by inserting a value to one of its vector. The code above did not work, so I tried this:

IntegerVector& x_i = X[index];

and received an error.

error: non-const lvalue reference to type 'IntegerVector'
      (aka 'Vector<13>') cannot bind to a temporary of type 'Proxy' (aka 'generic_proxy<19>')
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This question gets asked a lot in differing variants.

Here are some popular answers:

  1. Within C++ functions, how are Rcpp objects passed to other functions (by reference or by copy)?
  2. Update Rcpp::NumericMatrix passed by reference using RcppArmadillo submat()
  3. Rcpp pass by reference vs. by value
  4. Passing by reference a data.frame and updating it with rcpp
  5. Rcpp Update matrix passed by reference and return the update in R
  6. Passing large matrices to RcppArmadillo function without creating copy (advanced constructors)
  7. Rcpp: Inconsistent behavior with proxy model
  8. Why is my Rcpp implementation for finding the number of unique items slower than base R?

More details...

From the FAQ entry Rcpp changed the (const) object I passed by value that I wrote:

Rcpp objects are wrappers around the underlying R objects' SEXP, or S-expression. The SEXP is a pointer variable that holds the location of where the R object data has been stored R:Internals. That is to say, the SEXP does not hold the actual data of the R object but merely a reference to where the data resides. When creating a new Rcpp object for an R object to enter C++, this object will use the same SEXP that powers the original R object if the types match otherwise a new SEXP must be created to be type safe. In essence, the underlying SEXP objects are passed by reference without explicit copies being made into C++. We refer to this arrangement as a proxy model.

So, the & is just visual sugar as Rcpp objects already act as references.

Thus, the following would show the conclusion:

#include <Rcpp.h>

// [[Rcpp::export]]
void show_references(Rcpp::List X, 
                     Rcpp::IntegerVector y, 
                     int index = 0) {
  X[index] = y;
}

Example:

y_vec = c(-1L, 8L, 12L)
X_list = list(a = c(0L, 2L, 3L), b = c(42L, 50L, 30L))
X_list
# $a
# [1] 0 2 3
#
# $b
# [1] 42 50 30

show_references(X_list, y_vec)
X_list
# $a
# [1] -1  8 12
#
# $b
# [1] 42 50 30

The following Rcpp proxy model slides I created should further illustrate what is happening

enter image description here enter image description here

enter image description here enter image description here

Source: https://twitter.com/axiomsofxyz/status/938881541396197377


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...