Using Rcpp package to include C++ in R, I tried to compile my C++ file. Here is the error that came:
'function' in namespace 'std' does not name a template type
After investigation, I have been told that my code used some functionalities that are only available from C++ 11. So I need to add one line in my Makevars file. However, I found a vignette that says Makevars is not mandatory anymore :Rcpp vignette. How can I fix this problem?
Here is the part of the C++ script that doesn't work:
std::function<void(const state_type, state_type, const double)> eqsir2(const Rcpp::NumericVector theta) {
return [&theta](const state_type &x, state_type &dxdt, const double t) {
boost_array_to_nvec2(x, nvec);
my_fun22(nvec,t,theta);
nvec_to_boost_array2(nvec, dxdt);
}
To be able to use std::function
in C++ you have to include the right header via
#include <functional>
somewhere in your code base.
As for the R side, you have to tell the compiler that you want to use C++11 features. If you just have a .cpp
file that you include via Rcpp::sourceCpp
, you have to add
// [[Rcpp::plugins(cpp11)]]
to your .cpp
file.
If you are writing a R package (the vignette you are citing is meant for that), then a src/Makevars
file is no longer mandatory for using Rcpp
, but using CXX_STD
within src/Makevars
is the suggested way for requesting C++11 when wrting a package. Alternatively you can use SystemRequirements
in DESCRIPTION
. Citing from Writing R extensions:
In order to use C++11 code in a package, the package’s Makevars file (or Makevars.win on Windows) should include the line
CXX_STD = CXX11
Compilation and linking will then be done with the C++11 compiler.
Packages without a src/Makevars or src/Makefile file may specify that they require C++11 for code in the src directory by including ‘C++11’ in the ‘SystemRequirements’ field of the DESCRIPTION file, e.g.
SystemRequirements: C++11
If a package does have a src/Makevars[.win] file then setting the make variable ‘CXX_STD’ is preferred, as it allows R CMD SHLIB to work correctly in the package’s src directory.
In addition, you have to make sure that the signature of the returned function and the lambda are identical (see e.g. here). As it stands you are using references for only one of them. Both is possible, you just have to be consistent:
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
#include <functional>
// [[Rcpp::depends(BH)]]
#include <boost/array.hpp>
typedef boost::array<double, 3> state_type;
// references
std::function<void(const state_type&, state_type&, const double)> eqsir2(const Rcpp::NumericVector theta) {
return [&theta](const state_type &x, state_type &dxdt, const double t) {return;};
}
// no references
std::function<void(const state_type, state_type, const double)> eqsir(const Rcpp::NumericVector theta) {
return [&theta](const state_type x, state_type dxdt, const double t) {return;};
}