Search code examples
rcpprcpparmadillo

Use a C++ function as an argument for another C++ function called by an exported Rcpp function


I saw that it is possible to pass an R function as argument into C++ using Rcpp. For example, you can do:

// [[Rcpp::export]]
arma::mat example_cpp_func(Rcpp::Function my_r_func, arma::mat a){
  return Rcpp::as<arma::mat>(my_r_func(a));
}

That is fine but I'm searching for something slightly different.

Let be the following functions:

arma::mat f1(arma::mat& a){
  return a;
}

arma::mat func_2(Rcpp::Function g, arma::mat a){
  return Rcpp::as<arma::mat>(g(a));
}

I want to call func_2 in a third function using func_1 as argument. Is that possible? For example, I'm seeking to do:

// [[Rcpp::export]]
arma::mat func_3(arma::mat a){
  return func_2(func_1, a);
             ## ^^^^ Pass a C++ function as a parameter
}

This is possible with R, but when I tried with Rcpp/RcppArmadillo I get the following error:

could not convert ‘f1’ from ‘arma::mat ()(arma::mat&)’ {aka ‘arma::Mat ()(arma::Mat&)’} to ‘Rcpp::Function’ {aka ‘Rcpp::Function_Impl’}


Solution

  • Here's a complete example using the approach Ralf wrote in #1. You can use pure C/C++ function pointers here, although you can do more complex things with C++11.

    #include<RcppArmadillo.h>
    
    // [[Rcpp::depends(RcppArmadillo)]]
    
    typedef arma::mat (*functype)(arma::mat&);
    
    arma::mat f1(arma::mat& a){
      return a+1;
    }
    
    arma::mat f2(functype g, arma::mat a){
      return g(a);
    }
    
    //[[Rcpp::export]]
    arma::mat f3(arma::mat a){
      return f2(f1, a);
    }
    

    R side:

    > f3(matrix(1))
         [,1]
    [1,]    2