Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'function' in namespace 'std' does not name a template type

Tags:

c++

r

rcpp

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);
  }
like image 729
Anthony Hauser Avatar asked May 22 '18 10:05

Anthony Hauser


1 Answers

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;};
}
like image 111
Ralf Stubner Avatar answered Oct 20 '22 01:10

Ralf Stubner