作为第一步,您可以提取带有签名的函数
int foo(Rcpp::IntegerVector x, int val)
从你的工作代码。然后可以将其泛化为对任何iterable类型执行操作。签名:
template <typename T>
int foo(T x, typename std::iterator_traits<typename T::iterator>::value_type val)
不过,我们不能把这叫做R。如果R中的函数应该作用于不同的类型,它必须
SEXP
作为论据。
TYPEOF()
然后可用于确定R数据类型。将此集合用于整数向量:
#include <Rcpp.h>
template <typename T>
int iter_count(T x, typename std::iterator_traits<typename T::iterator>::value_type val) {
int m = 0;
for(typename T::iterator iter = x.begin(); iter < x.end(); ++iter) {
if(*iter == val) ++m;
}
return m;
}
// [[Rcpp::export]]
int count(SEXP x, SEXP val) {
switch( TYPEOF(x) ) {
case INTSXP: {
return iter_count(Rcpp::as<Rcpp::IntegerVector>(x),
Rcpp::as<Rcpp::IntegerVector>(val)(0));
}
default: {
Rcpp::stop("incompatible SEXP encountered");
}
}
}
/*** R
set.seed (1005)
x <- sample(1:5L, size = 10, replace = T)
y <- 3L
count(x,y)
*/
我在这里使用Rcpp属性:将其保存为
.cpp
文件和使用
Rcpp::sourceCpp("...")
在上面。
顺便说一下,在你的代码中,这看起来很可疑:
NumericVector xx(x);
int n = xx.size();
NumericVector yy = xx + n;
你想知道
xx
? 然后使用
xx.end()
或
end(xx)
,它不是
NumericVector
. 你的代码创建了一个新的
数字向量
其中的内容
二十
已经被
二十
. 这里是使用Rcpp属性的等效代码:
Rcpp::cppFunction('NumericVector foo(NumericVector xx) {
int n = xx.size();
NumericVector yy = xx + n;
return yy;
}
')
set.seed(42)
foo(runif(3))
# [1] 3.914806 3.937075 3.286140