Rcpp 参数范围向上传播?
Rcpp parameter scope propagates up?
我最近一直在做很多 Rcpp 编码,偶然发现了一些让我困惑的事情。我的印象是,任何给定的函数在调用时都会创建其特定参数的副本,然后一旦函数完成,这些变量就会被销毁。但是,当我使用 List
类型时,我发现情况似乎并非如此。在某些情况下,我可能需要修改不同函数内的列表元素,但希望 'higher' 范围内的列表保持不变。这是一个非常简单的例子来说明这个问题:
test.cpp
//[[Rcpp::export]]
int list_length(List myList){
// some sort of modification that could be needed locally
for (int w=0; w < myList.size(); w++) {
myList[w] = 13;
}
// return whatever metric
return myList.size();
}
//' @export
//[[Rcpp::export]]
SEXP list_int(List myList){
// only want the int output from function
int out = list_length(myList);
return(List::create(myList,
wrap(out)));
}
test.R
# create simple list
myList <- as.list(seq(4))
# call Rcpp function
list_int(myList)
# output
[[1]]
[[1]][[1]]
[1] 13
[[1]][[2]]
[1] 13
[[1]][[3]]
[1] 13
[[1]][[4]]
[1] 13
[[2]]
[1] 4
如您所见,列表在函数上方的范围内被修改。我在这里遗漏了什么吗?
是的,您错过了 SEXP 传递指针。
这有很好的记录,我们通常将我们的类型称为 'shallow proxy objects'。
我最近一直在做很多 Rcpp 编码,偶然发现了一些让我困惑的事情。我的印象是,任何给定的函数在调用时都会创建其特定参数的副本,然后一旦函数完成,这些变量就会被销毁。但是,当我使用 List
类型时,我发现情况似乎并非如此。在某些情况下,我可能需要修改不同函数内的列表元素,但希望 'higher' 范围内的列表保持不变。这是一个非常简单的例子来说明这个问题:
test.cpp
//[[Rcpp::export]]
int list_length(List myList){
// some sort of modification that could be needed locally
for (int w=0; w < myList.size(); w++) {
myList[w] = 13;
}
// return whatever metric
return myList.size();
}
//' @export
//[[Rcpp::export]]
SEXP list_int(List myList){
// only want the int output from function
int out = list_length(myList);
return(List::create(myList,
wrap(out)));
}
test.R
# create simple list
myList <- as.list(seq(4))
# call Rcpp function
list_int(myList)
# output
[[1]]
[[1]][[1]]
[1] 13
[[1]][[2]]
[1] 13
[[1]][[3]]
[1] 13
[[1]][[4]]
[1] 13
[[2]]
[1] 4
如您所见,列表在函数上方的范围内被修改。我在这里遗漏了什么吗?
是的,您错过了 SEXP 传递指针。
这有很好的记录,我们通常将我们的类型称为 'shallow proxy objects'。