假设我有一个名为“packA”的 R 包,其中包含以下文件“funcA.cpp”:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r, cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcA (arma::vec& x) {
x += 1;
}
从 R 调用此函数会产生将 1 原地添加到向量的每个元素的预期结果:
> vec <- c(1, 2, 3)
> funcA(vec)
> vec
[1] 2 3 4
现在说我有第二个包“packB”,它想调用函数“funcA”。它包含以下名为“funcB.cpp”的文件:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcB() {
arma::vec x = {1, 2, 3};
Rcout << x << "\n";
packA::funcA(x);
Rcout << x << "\n";
}
调用此函数不再产生所需的结果,因为看起来向量 x 不再就地修改:
> funcB()
1.0000
2.0000
3.0000
1.0000
2.0000
3.0000
有没有办法在仍然使用 Rcpp 的同时保留 C++ 函数的就地操作?提前感谢您的任何建议。
编辑: 我根据 Dirk Eddelbüttel 的建议修改了“funcB.cpp”:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcB(arma::vec& y) {
packA::funcA(y);
}
不幸的是,从 R 调用函数时的结果是相同的:
> vec <- c(1, 2, 3)
> funcB(vec)
> vec
[1] 1 2 3
编辑 2:
经过一些进一步的实验,我注意到事情一旦arma::vec& x
出现在funcA
. 只需使用NumericVector
作品:
“funcA.cpp”
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r, cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcA (NumericVector& num_x) {
num_x[2] = 10 + num_x[2];
}
> vec <- c(1, 2, 3)
> funcA(vec)
> vec
[1] 1 2 13
“funcB.cpp”
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcB(NumericVector& num_y) {
packA::funcA(num_y);
}
> vec <- c(1, 2, 3)
> funcB(vec)
> vec
[1] 1 2 13
即使使用高级arma::vec
构造函数来创建具有共享内存的犰狳向量,只要输入是 aNumericVector
:
“funcA.cpp”
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r, cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcA (NumericVector& num_x) {
arma::vec x_int = arma::vec(num_x.begin(), 3, false, false);
x_int(2) = 10 + x_int(2);
}
> vec <- c(1, 2, 3)
> funcA(vec)
> vec
[1] 1 2 13
> vec <- c(1, 2, 3)
> funcB(vec)
> vec
[1] 1 2 13
尝试相同的事情arma::vec
不再有效。
“funcA.cpp”
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r, cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcA (arma::vec& x) {
arma::vec x_int = arma::vec(x.begin(), 3, false, false);
x(2) = 10 + x(2);
}
> vec <- c(1, 2, 3)
> funcA(vec)
> vec
[1] 1 2 13
“funcB.cpp”
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;
// [[Rcpp::export]]
void funcB(arma::vec& y) {
packA::funcA(y);
}
> vec <- c(1, 2, 3)
> funcB(vec)
> vec
[1] 1 2 3