Используйте функцию C ++ в качестве аргумента для другой функции C ++, вызываемой экспортированной функцией Rcpp - PullRequest
1 голос
/ 26 апреля 2019

Я видел, что можно передать функцию R в качестве аргумента в C ++ , используя Rcpp. Например, вы можете сделать:

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

Это нормально, но я ищу что-то немного другое.

Позвольте быть следующие функции:

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));
}

Я хочу вызвать func_2 в третьей функции, используя func_1 в качестве аргумента. Это возможно? Например, я стараюсь сделать:

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

Это возможно с R, но когда я попытался с Rcpp / RcppArmadillo, я получаю следующую ошибку:

не удалось преобразовать 'f1' из 'arma :: mat () (arma :: mat &)' {aka 'arma :: Mat () (arma :: Mat &)'} в 'Rcpp :: Function '{aka' Rcpp :: Function_Impl '}

Ответы [ 2 ]

3 голосов
/ 26 апреля 2019

Вот полный пример, использующий подход, который Ральф написал в # 1.Вы можете использовать чистые указатели функций C / C ++ здесь, хотя вы можете делать более сложные вещи с 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:

> f3(matrix(1))
     [,1]
[1,]    2
2 голосов
/ 26 апреля 2019

В сообщении об ошибке говорится, что все, что есть: Для C ++ f1 - это функция, которая ожидает arma::mat в качестве аргумента и возвращает arma::mat. Это сильно отличается от Rcpp::Function, который представляет собой тонкую оболочку вокруг функции R. Я вижу три возможности:

  1. Напишите альтернативную f2 функцию, которая ожидает указатель функции или std::function (требуется C ++ 11) с соответствующими аргументами.

  2. Добавьте аргумент типа Rcpp::Function к f3, который используется в вызове к f2.

  3. Получить соответствующую функцию R с помощью Rcpp::Environment и Rcpp:Function.

Без дополнительной информации о сценарии использования сложно дать совет.

...