RcppArmadillo przekazuje funkcję zdefiniowaną przez użytkownika

Rozważ następujący kod R,

## ----------- R version -----------

caller <- function(x=1:3, fun = "identity", ...){

  ## do some other stuff
  ## ...
  ## then call the function
  eval(call(fun, x))

}

fun1 <- function(x, ...){
  x + x
}

fun2 <- function(x, a = 10) a * x

caller(fun = "fun1")
caller(fun = "fun2")

Użytkownik może przekazać nazwę funkcji „fun”, która jest używana przezcaller. Chcę wykonać to samo zadanieRcppArmadillo obiekty (oczywiście w ramach bardziej złożonego zadania). Funkcja zostanie zdefiniowana wC++, a użytkownik wybiera go na poziomie R, odwołując się do jego nazwy:

caller_cpp(1:3, "fun1_cpp")

lub

caller_cpp(1:3, "fun2_cpp")

itp.

Oto moja naiwna próba wywołania funkcji, która nawet się nie kompiluje:

## ----------- C++ version -----------

library(Rcpp)
require( RcppArmadillo )    

sourceCpp( code = '

       // [[Rcpp::depends("RcppArmadillo")]]

       #include <RcppArmadillo.h>

       using namespace arma ; 
       using namespace Rcpp ;


       colvec fun1_cpp(const colvec x)
      {
       colvec y ;
       y = x + x;
       return (y);
      }

       colvec fun2_cpp(const colvec x)
      {
       colvec y ;
       y = 10*x;
       return (y);
      }

     // mysterious pointer business in an attempt 
     // to select a compiled function by its name

      typedef double (*funcPtr)(SEXP);
      SEXP putFunPtrInXPtr(SEXP funname) {
            std::string fstr = Rcpp::as<std::string>(funname);
            if (fstr == "fun1")
                return(Rcpp::XPtr<funcPtr>(new funcPtr(&fun1_cpp)));
            else if (fstr == "fun2")
            return(Rcpp::XPtr<funcPtr>(new funcPtr(&fun2_cpp)));

       }

       // [[Rcpp::export]]
       colvec caller_cpp(const colvec x, character funname)
      {
       Rcpp::XPtr fun = putFunPtrInXPtr(funname);
       colvec y ;
       y = fun(x);
       return (y);
      }

   ')

Edytować: zaadaptowałem przykład po podążaniu za sugestią Dirka, aby spojrzeć na RcppDE.

questionAnswers(1)

yourAnswerToTheQuestion