4

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?

0

3 Answers 3

2

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;
}")
Sign up to request clarification or add additional context in comments.

3 Comments

You can trivially cast that so that what is created as a Rcpp::IntegerVector gets returned as std::vector<int>. Rcpp makes the conversion automatically for you.
Well the only reason I am using std::vector in the first place is because inside the function I need to grow/fill that vector to match the length of another vector. Does IntegerVector have an equivalent to resize()? EDIT: I would up vote this answer but I supplied it.
Which vector type to use when has been discussed numerous times here and on the rcpp-devel list.
1

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

11 Comments

This is what I used to do. However, compileAttributes() trashes any changes made in RcppExports.R. I am trying to only maintain one file (the cpp file).
Just use a second R file. Call your autogenerated foo_impl() and have foo() call foo_impl() with the trick shown here.
Well if it "sucks" so badly then maybe Rcpp is not for you. Sorry. Not everything can be done in a one-file solution, and as you also supplied this on GitHub (though everybody knows that crossposting sucks worse) I followed up there. Your example ain't working.
don't put words in my mouth, "sucks" was your word not mine
Piling up options here instead of useless vocabulary battles; I'm planning to extend how to give defaults in the attributes package, which is compatible with Rcpp and other implementations of R/C++. github.com/Rcpp11/attributes/issues/36
|
0

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.

2 Comments

Actually, Rcpp does export default values. It just doesn't seem to work with primitive types.
What Rcpp does is to convert the rhs of = into R code. It only know how to deal with certain things. I'm experimenting with an alternative way to set the formals of the R function with R code in the attributes package. github.com/Rcpp11/attributes/issues/36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.