[英]Rcpp pass vector of length 0 (NULL) to cppfunction
I have a cppFunction
with a vector ints
as input, eg: 我有一个带向量的
ints
作为输入的cppFunction
,例如:
library(Rcpp)
cppFunction('double test2(NumericVector ints) {
return 42;
}')
The output is correct if passing a vector of length at least 1: 如果传递长度至少为1的向量,则输出正确:
> test2(1)
[1] 42
> test2(1:10)
[1] 42
For input of length 0 however I get: 对于长度为0的输入,我得到:
> test2(c())
Error: not compatible with requested type
Is there any way to pass a vector of length 0 or larger to my function? 有没有办法将长度为0或更大的向量传递给我的函数? Ie my expected output is:
即我的预期输出是:
> test2_expectedoutput(c())
[1] 42
I know I could control for this in R by checking in R first and calling a different version of the function but would like to avoid this. 我知道我可以通过首先检入R并调用函数的不同版本来控制R,但是我想避免这种情况。 I expect there is some easy solution out there since within cpp I could also have a
NumericVector
of length 0 if I understand correctly what NumericVector zero;
我希望有一些简单的解决方案,因为在cpp内我也可以有一个长度为0的
NumericVector
,如果我正确理解NumericVector zero;
does. 确实。 The only related question I could find was this on how to return a NULL object from within a Rcpp function to R .
我能找到的唯一相关问题就是如何将一个NULL对象从Rcpp函数返回到R。
A few months ago we added the ability to pass as Nullable<T>
which may be what you want here. 几个月前,我们添加了传递为
Nullable<T>
的能力,这可能是你想要的。
Here is a simple example: 这是一个简单的例子:
#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)
*/
and its output: 及其输出:
R> sourceCpp("/tmp/null.cpp")
R> checkNull(1:3)
Sum is 6
[1] TRUE
R> checkNull(NULL)
Nothing to see
[1] FALSE
R>
By being templated we respect the intended type but clearly differentiate between being there, and not. 通过模仿,我们尊重预期的类型,但明确区分存在与否。
The c()
calls produces NULL
which is not a numeric
vector. c()
调用产生NULL
,它不是numeric
向量。 This generates the error when test2
is called. 这会在调用
test2
时生成错误。 You can build a numeric vector of length 0 through numeric
: 您可以构建一个长度为0到
numeric
的数字向量:
#check what `c()` does
str(c())
# NULL
# now we try numeric(0)
test2(numeric(0))
#[1] 42
As a suggestion, I think that C
, Fortran
or C++
functions should rarely be called directly; 作为一个建议,我认为很少直接调用
C
, Fortran
或C++
函数; much better to write a wrapper that does some preliminary operations, like type conversions and similar. 编写一个执行一些初步操作的包装器会更好,例如类型转换和类似操作。 Something like the following:
类似于以下内容:
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'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.