在Rcpp中声明一个变量作为引用

use*_*524 4 rcpp rcpp11

在C++中,我们可以将变量声明为引用.

int a = 10;
int& b = a;
Run Code Online (Sandbox Code Playgroud)

如果我们设置b=15,a也会改变.

我想在Rcpp做类似的事情.

List X = obj_from_R["X"];
IntegerVector x_i = X[index];
x_i = value;
Run Code Online (Sandbox Code Playgroud)

我想X通过在其向量之一中插入一个值来更新R中的对象.上面的代码不起作用,所以我尝试了这个:

IntegerVector& x_i = X[index];
Run Code Online (Sandbox Code Playgroud)

并收到错误.

error: non-const lvalue reference to type 'IntegerVector'
      (aka 'Vector<13>') cannot bind to a temporary of type 'Proxy' (aka 'generic_proxy<19>')
Run Code Online (Sandbox Code Playgroud)

coa*_*ess 9

这个问题在不同的变体中被问到很多.

以下是一些受欢迎的答案:

  1. 在C++函数中,Rcpp对象如何传递给其他函数(通过引用或通过复制)?
  2. 使用RcppArmadillo submat()更新通过引用传递的Rcpp :: NumericMatrix
  3. Rcpp通过引用传递而不是通过值传递
  4. 通过引用传递data.frame并使用rcpp更新它
  5. Rcpp更新矩阵通过引用传递并返回R中的更新
  6. 将大型矩阵传递给RcppArmadillo函数而不创建副本(高级构造函数)
  7. Rcpp:代理模型的行为不一致
  8. 为什么我的Rcpp实现用于查找比基本R慢的唯一项目数?

更多细节...

从FAQ条目中,Rcpp改变了我传递的(const)对象,我写的是:

Rcpp对象是底层R对象的SEXP或S表达式的包装器.它SEXP是一个指针变量,用于保存R对象数据存储位置R:Internals.也就是说,SEXP它不保存R对象的实际数据,而仅仅是对数据所在位置的引用.为R对象创建新的Rcpp对象以输入C++时,如果类型匹配,则此对象将使用为原始R对象提供动力的相同SEXP,否则必须创建新的SEXP以保证类型安全.从本质上讲,底层SEXP对象是通过引用传递的,而不会将显式副本转换为C++.我们将此安排称为代理模型.

所以,&只是视觉糖,因为Rcpp对象已经作为参考.

因此,以下将显示结论:

#include <Rcpp.h>

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

例:

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
Run Code Online (Sandbox Code Playgroud)

我创建的以下Rcpp代理模型幻灯片应该进一步说明发生了什么

在此输入图像描述 在此输入图像描述

在此输入图像描述 在此输入图像描述

资料来源:https://twitter.com/axiomsofxyz/status/938881541396197377


归档时间:

查看次数:

607 次

最近记录:

7 年,10 月 前