Declare a variable as a reference in Rcpp

血红的双手。 提交于 2019-12-28 12:44:29

问题


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>')

回答1:


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

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



来源:https://stackoverflow.com/questions/48363076/declare-a-variable-as-a-reference-in-rcpp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!