Rcpp将长度为0(NULL)的向量传递给CPPP函数

Rcpp将长度为0(NULL)的向量传递给CPPP函数,r,rcpp,R,Rcpp,我有一个cpp函数,输入向量ints,例如: library(Rcpp) cppFunction('double test2(NumericVector ints) { return 42; }') 如果传递长度至少为1的向量,则输出正确: > test2(1) [1] 42 > test2(1:10) [1] 42 对于长度为0的输入,我得到: > test2(c()) Error: not compatible with

我有一个
cpp函数
,输入向量
ints
,例如:

library(Rcpp)
cppFunction('double test2(NumericVector ints) {
            return 42;
            }')
如果传递长度至少为1的向量,则输出正确:

> test2(1)
[1] 42
> test2(1:10)
[1] 42
对于长度为0的输入,我得到:

> test2(c())
Error: not compatible with requested type
有没有办法将长度为0或更大的向量传递给我的函数?即,我的预期产出是:

> test2_expectedoutput(c())
[1] 42
我知道我可以在R中通过先签入R并调用不同版本的函数来控制它,但我希望避免这种情况。我希望有一些简单的解决方案,因为在cpp中,如果我正确理解什么是
NumericVector zero,我也可以有长度为0的
NumericVector
可以。我能找到的唯一相关问题是

调用
c()
生成的
NULL
不是
numeric
向量。这会在调用
test2
时生成错误。您可以构建长度为0到
numeric
的数值向量:

#check what `c()` does
str(c())
# NULL

# now we try numeric(0)
test2(numeric(0))
#[1] 42
作为建议,我认为不应该直接调用
C
Fortran
C++
函数;编写一个进行一些初步操作(如类型转换和类似操作)的包装器要好得多。如下所示:

test2Wrapp<-function(x) test2(as.numeric(x))
test2Wrapp(c())
#[1] 42
#This has the benefit to not calling the internal routines in cases where conversion isn't possible
test2Wrapp(iris)
#Error: (list) object cannot be coerced to type 'double'

test2Wrapp几个月前,我们添加了传递为
Nullable
的功能,这可能正是您想要的

下面是一个简单的例子:

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
bool checkNull(Nullable<NumericVector> x) {
  if (x.isNotNull()) {
    // do something
    NumericVector xx(x);
    Rcpp::Rcout << "Sum is " << sum(xx) << std::endl;
    return true;
  } else {
    // do nothing
    Rcpp::Rcout << "Nothing to see" << std::endl;
    return false;
  }
}

/*** R
checkNull(1:3)
checkNull(NULL)
*/

通过模板化,我们尊重预期的类型,但明确区分存在与否。

请参见
str(c())
。它不是一个数值向量
numeric(0)
是一个长度为0的数值向量。@nicola解决了这个问题,谢谢!是否愿意作为答案发布?
raw()
logical()
integer()
double()
complex()
vector()
的输入也可以在这里使用。是的,这是由于特定的
Rcpp
接口以及它接受的
NumericVector
。显然,
logical
raw
complex
都符合条件。我不想吹嘘太多,但它包含了他的答案,因为你还可以在幕后得到他推荐的所有健全检查。而且
NULL
比长度0更明确。我接受了nicolas的答案,因为这是第一个答案,并回答了我的问题(在这个答案发布之前)。它提供了一个快速而简单的解决方法,对我来说效果很好,而这个答案展示了如何以更一般的方式在Rcpp中处理我的问题。作为Rcpp的新手,我从这两个答案中学到了很多,并且相信它们是互补的。请允许我删除之前的评论,以避免误解,再次感谢+1(我不是建议/要求你这样做,而是…)人们一直在交换接受的选票。SO的目的是让最好的解决方案产生泡沫。选择你认为对你的问题最好的回答。这就是绩效体系应该如何运作的。
R> sourceCpp("/tmp/null.cpp")

R> checkNull(1:3)
Sum is 6
[1] TRUE

R> checkNull(NULL)
Nothing to see
[1] FALSE
R>