I'm trying to pass arguments in rcpp function using ... but it is not working. How to do this correctly?
NumericVector function(SEXP xR, ...){
NumericVector x(xR);
int lenx = x.size();
NumericVector ret(lenx);
for(int i=0; i < lenx; i++){
if(x[i]<0){
ret[i] = 0;
}else if(x[i]>1){
ret[i] = 1;
}else{
ret[i] = anotherfunction(x[i], ...);
}
}
return ret;
}
In current version I get this error:
expected primary-expression before '...' token
Rcpp11
has the concept of variable number of arguments with the Dots
and NamedDots
class. You'd do something like this:
#include <Rcpp11>
List force_dots( const Dots& dots ){
List out(n) ;
for( int i=0; i<n; i++){
out[i] = Rcpp_eval( dots.promise(i), dots.environment(i)) ;
}
return out ;
}
// [[export]]
List dots_example(NumericVector x, Dots dots){
int n = dots.size() ;
List args = force_dots(dots) ;
return args ;
}
/*** R
dots_example(1:10, "e" )
# [[1]]
# [1] "e"
*/
When you use attributes::sourceCpp
on this file, you get an R function that has ellipsis:
> dots_example
function(x, ...){
res <- .Call( "sourceCpp_dots_example" , x, environment())
res
}
This only partly answers the question, i.e. how to pass down to C++ a variable number of arguments from R.
You'd also need something similar to R's do.call
for when you call the another_function
function. For now you sort of have to do it manually until we find a way to implement a useful do_call
You may be confusing the R-language construct ...
with something you assume also exists in C++. And while C++ does have varargs
that is not supported by Rcpp due to the interface from R. All we have is the .Call()
interface
SEXP somefunction(SEXP a, SEXP b, SEXP c, ...)
and here the ...
is used in a literal sense just for the exposition: You can have 0, 1, 2, 3, ... SEXP
arguments. But those you use must be fully qualified. In short, using ...
results in the syntax error you see. See Section 5.9 of Writing R Extensions for details.
And as a side note, this is why we have macro-generated code in Rcpp. Now, with C++11 you can also use variadic templates in C++ code (which Rcpp11 uses to great effect in its internal code) but that of course does not alter the interface to R which is still the same .Call()
interface, and hence the same constraint. Variadic templates are very nice, and open for use in your C++ code with either Rcpp or Rcpp11, but they do not change the interface to R. You need a fixed set of arguments, and can not rely on a variable number.
That said, if you just pass a List
object as one of your arguments, then you can traverse it by position or name at will and check the content. That is the closest in spirit to your question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With