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>')
This question gets asked a lot in differing variants.
Here are some popular answers:
- Within C++ functions, how are Rcpp objects passed to other functions (by reference or by copy)?
- Update Rcpp::NumericMatrix passed by reference using RcppArmadillo submat()
- Rcpp pass by reference vs. by value
- Passing by reference a data.frame and updating it with rcpp
- Rcpp Update matrix passed by reference and return the update in R
- Passing large matrices to RcppArmadillo function without creating copy (advanced constructors)
- Rcpp: Inconsistent behavior with proxy model
- 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, theSEXP
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
Source: https://twitter.com/axiomsofxyz/status/938881541396197377
来源:https://stackoverflow.com/questions/48363076/declare-a-variable-as-a-reference-in-rcpp