Search code examples
c++rstlrcppr-package

Package with Rcpp ignores #include <stack>


I want to use a std::stack in a C++ function inside an R package. Consider the following example C++ file:

// [[Rcpp::plugins(cpp20)]]
#include <Rcpp.h>
#include <stack>

// [[Rcpp::export]]
Rcpp::XPtr<std::stack<int> > stack_c(Rcpp::IntegerVector& v) {
  std::stack<int>* s = new std::stack<int>;
  s->push(v[0]);
  Rcpp::XPtr<std::stack<int> > p(s);
  return p;
}

Compiling it outside an R package with Rcpp::sourceCpp() works. However, it does not work inside an R package.

The R package contains the mentioned C++ file and a Makevars file with the line CXX_STD = CXX20 in the src directory.

An R file in the R directory calls the function.

#' @export
stack_r <- function(x) {
  return(stack_c(x))
}

The NAMESPACE file contains the usual Rcpp lines.

useDynLib(testpkg, .registration=TRUE)
importFrom(Rcpp, evalCpp)
exportPattern("^[[:alpha:]]+")

And the DESCRIPTION file imports and links to Rcpp.

Imports: Rcpp (>= 1.0.13)
LinkingTo: Rcpp

When trying to install the package, I get the following compiler error:

RcppExports.cpp:14:18: error: 'stack' is not a member of 'std'
   14 | Rcpp::XPtr< std::stack<int> > create_stack(Rcpp::IntegerVector& v);
      |                  ^~~~~
RcppExports.cpp:5:1: note: 'std::stack' is defined in header '<stack>'; did you forget to '#include <stack>'?

I do not know why this occurs. The C++ file clearly includes the line #include <stack>.

Do I need to set other compiler flags?

I use Windows 11 with the latest Rtools, R, and Rcpp versions.


Solution

  • The C++ file that you wrote has the correct header. But the C++ file generated by Rcpp, namely RcppExports.cpp, does not yet know about the additional header. To provide that information, you can use an file with a special name as described in detail in the corresponding vignette in the section Types in Generated Code. One solution is inst/include/testpkg_types.h as your package is called testpkg. Add #include <stack> to that file, and re-run compileAttributes() (which for example RStudio runs for you when you rebuild your package). The updated RcppExports.cpp will now have an #include <stack> as well, and compile. See the vignette for more options.

    A simpler shortcut is to not use std::stack in your return type but to simply use SEXP.