【发布时间】:2020-01-04 19:44:48
【问题描述】:
我正在尝试在 Rcpp 中创建某种 sapply 函数,其工作原理如下:
apply_cpp_fun(x, fun, ...)函数有两个参数:任何类型的向量x,以及任何 cpp 函数fun,加上fun中所需的可选参数(例如bool na_rm)。在示例中,我保持简单,只需x和fun。我希望将
fun应用于x的选定元素(可能的fun输出 - bool、int、double、string)。我不想申请在apply_cpp_fun内被多次调用。apply_cpp_fun的输出是依赖于fun输出的任何类型的向量(可以不同于x)。fun被调用 n 次,以产生输出向量res的每个元素。
我试图通过但每次输出变为Rcpp::List 而不是Rcpp::Vector<double> 来实现这一点。
这是一个代码,我没有写整个 apply_cpp_fun 以使示例更短。如您所见,即使我通过<double>function,模板也会得到描述为double (*)(Rcpp::Vector<14, Rcpp::PreserveStorage>) 的Vector。
#include <Rcpp.h>
double cpp_sum(Rcpp::NumericVector x) {
int n = x.size();
double cursum = 0;
for (int i = 0; i < n; i++) {
cursum += x(i);
}
return cursum;
}
template <int ITYPE, typename ftype>
Rcpp::Vector<Rcpp::traits::r_sexptype_traits<ftype>::rtype>
apply_cpp_fun(Rcpp::Vector<ITYPE>& x,
ftype fun) {
int n = x.size();
double xx = 5.0;
# typenames
Rcpp::Rcout << "type of xx: " << demangle(typeid(xx).name()).c_str() << std::endl;
Rcpp::Rcout << "function type: " << demangle(typeid(ftype).name()).c_str() << std::endl;
const int OTYPE = Rcpp::traits::r_sexptype_traits<ftype>::rtype;
Rcpp::Rcout << "SEXP type: " << OTYPE << std::endl;
# apply fun n-times
Rcpp::Vector<OTYPE> res(n);
for (int i = 0; i < n; i++) {
res(i) = fun(x);
}
return res; # return vector
}
// [[Rcpp::export]]
SEXP cumsum_cpp(Rcpp::NumericVector x) {
return apply_cpp_fun(x, cpp_sum);
}
调用函数查看结果
cumsum_cpp(as.numeric(1:2))
# type of xx: double
# function type: double (*)(Rcpp::Vector<14, Rcpp::PreserveStorage>)
# SEXP type: 19
# [[1]]
# NULL
#
# [[2]]
# NULL
如何解决这个问题以保持应用程序对输入类型和输出的灵活性? 感谢您的建议。
【问题讨论】:
-
你可以试试
RCPP_RETURN_VECTOR宏。 SO上有几个关于它的问题。 -
谢谢,我会探索这种可能性
-
要获得函数的返回类型,你需要en.cppreference.com/w/cpp/types/result_of