3
votes

I am trying to write a C++/Rcpp function that has an optional argument whos default needs to be a vector of length 1 with a value of 0. The following does not compile properly:

cppFunction("std::vector<int> test(std::vector<int> out = {0}) {
  return out;
}")

I get the following error:

Error in cppFunction("std::vector test(std::vector out = {1}) {\n return out;\n}") : No function definition found In addition: Warning messages: 1: No function found for Rcpp::export attribute at fileee5f629605d7.cpp:5 2: In sourceCpp(code = code, env = env, rebuild = rebuild, showOutput = showOutput, : No Rcpp::export attributes or RCPP_MODULE declarations found in source

What is the right way to do this?

3

3 Answers

2
votes

This answer was posted on the Rcpp issue tracker. This is the desired result that I wanted just not with std::vector.

cppFunction("IntegerVector test(IntegerVector out = IntegerVector::create(0)) {
   return out;
}")
1
votes

You could wrap the underlying C++ function in an R function that uses a default value:

#include <Rcpp.h>
#include <vector>
// [[Rcpp::plugins(cpp11)]]

// [[Rcpp::export]]
std::vector<int> cpp_test(const std::vector<int>& x)
{
  return x;
}

/*** R

test <- function(X = c(0L))
{
  cpp_test(X)
}

test()

test(c(1:5))

*/

which gives you

> Rcpp::sourceCpp('~/RcppFiles/cpp_test.cpp')
> test()
[1] 0

> test(c(1:5))
[1] 1 2 3 4 5
0
votes

Currently the Rcpp package didn't support the exporting the default values. There are several packages to improve this (including Rcpp11), thought, I have a solution on Rcpp with RCPP_MODULES:

library("Rcpp")

cppFunction(plugins=c("cpp11"),'NumericVector test(std::vector<int> out) {
  return wrap(out);
}

RCPP_MODULE(mod) {
  function("test",&test,List::create( _["out"] = std::vector<int>({0})), "Simple description");
}', verbose=TRUE,rebuild=TRUE)

I change the return type, thought, it work even if you return std::vector<int>.

So, how this works: it just creates a documentation entry with the default value, third argument for RCPP_MODULES.

With just {0} my R crashes, so, it's necessary for me to put std::vector explicitly.