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.
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
.