r语言 - 为什么当我使用 Rcpp 编写时,我不需要包含一些我应该以普通C++编写的库

r - Why when I write with Rcpp I do not need to include some libraries which I should include writing in plain C++?

本文关键字:我应该 包含一 C++ 不需要 为什么 语言 Rcpp      更新时间:2023-10-16

我正在使用Rcpp运行以下代码块

src <- '
Rcpp::NumericVector vec(vx);
double p = Rcpp::as<double>(dd);
double sum = 0.0;
for (int i=0; i<vec.size(); i++) {
sum += pow(vec[i], p);
}
return Rcpp::wrap(sum);
'
fun <- cxxfunction(signature(vx="numeric", dd="numeric"),
src, plugin="Rcpp")
fun(1:4,2)

我得到了结果 30(这是正确的)。如果我以普通C++运行函数 pow(x,y),我需要添加

#include <math>

为什么我不需要在 Rcpp 下写作?

狭隘地回答您的问题:

  • 因为您的#include <Rcpp.h>会导致为您包含其他标头

因为Rcpp.h包括它们供您使用(以及乔希对 grep 的好技巧;我仍然会在命令行上这样做)。 您使用内联包中的旧cxxfunction(),它会为您添加Rcpp.h include。 Rcpp属性甚至更容易(请参阅我对CDterman答案的评论),它还为您添加了所需的标头。

另请注意,pow()既被定义为标量函数(即double输入,double输出),又如 CDeterman 所说,在 Rcpp 糖中(它以矢量化方式用于 Rcpp 对象)。 您可以通过显式命名空间使用来控制使用哪个:即std::pow()会得到前者。

pow函数是 Rcpp Sugar 的一部分,当你在 R 对象上使用它时。 我不认为数学库中的每个函数都已转换,因此不要期望每个函数都适用于 R 对象。 您可以在此处看到小插图,其中详细介绍了实现的一些功能。

现在,如果您想知道为什么在普通C++对象上使用pow时不需要数学库,例如这个非常简单的示例:

src <- '
double t = 2;
double o = pow(t, 2);
return wrap(o);
'
fun <- cxxfunction(signature(),
                   src, plugin="Rcpp")
fun()
[1] 4

这是因为 Rcpp 确实像您怀疑的那样默认导入标头。 标头列表显示在源代码中。 您感兴趣的文件可能是这个,您将看到包含 cmath 库。 大多数基本C++标头似乎都位于此处。

也就是说,您可能会发现浏览源代码很乏味,Josh 建议的调用确实是快速浏览库的特别之处,但您还应该了解信息的实际来源,而不是单一调用的魔力,恕我直言。