Потокобезопасный указатель на функцию с Rcpp и RcppParallel через std::shared_ptr

Я хотел бы использовать указатель на функцию безопасности потока, который будет применяться в RcppPrallel работника. Но у меня уже есть проблемы с этим крошечным примером. Неважно, если я использую его в пакете и добавить SystemRequirements: C++11 в файле DESCRIPTION, или используйте его в стандартном файле cpp и добавьте // [[Rcpp::plugins(cpp11)]] Я получаю те же ошибки: "shared_ptr" не является членом "std". Кто-нибудь может мне помочь, пожалуйста! Спасибо!

#include <Rcpp.h>
using namespace Rcpp;
using namespace std;


double f1 (double x, double y) {
   return x * y;
}

double f2 (double x, double y) {
   std::shared_ptr<int> p1;
   std::cout << "p1: " << p1.use_count() << '\n';
   return x + y;
}

typedef double (*funcPtr)(double x, double y);

std::shared_ptr<funcPtr> selectf(std::string abc) {

   std::shared_ptr<funcPtr> fp = NULL;

   if(abc == "a"){
      fp = std::make_shared<funcPtr>(new funcPtr(&f1));
   }else {
      fp = std::make_shared<funcPtr>(new funcPtr(&f2));
   }
   return fp;
}


// [[Rcpp::export]]
double f0(double x, double y, std::string abc){
   double ret;
   df = selectf(abc);
   ret = df(x, y);
   return(ret);
}


/*** R
if(FALSE){
   f0(10, 10, "a")
}
*/

Системная информация:

> sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=German_Germany.1252 
[2] LC_CTYPE=German_Germany.1252   
[3] LC_MONETARY=German_Germany.1252
[4] LC_NUMERIC=C                   
[5] LC_TIME=German_Germany.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets 
[6] methods   base     

loaded via a namespace (and not attached):
 [1] compiler_3.5.0  R6_2.2.2        magrittr_1.5   
 [4] tools_3.5.0     withr_2.1.2     roxygen2_6.0.1 
 [7] yaml_2.1.19     memoise_1.1.0   Rcpp_0.12.18   
[10] xml2_1.2.0      stringi_1.2.2   stringr_1.3.1  
[13] digest_0.6.15   commonmark_1.5  devtools_1.13.5

2 ответа

Решение

std::shared_ptr объявлен в шапке <memory>, Пытаться:

#include <memory>

Вы можете найти документацию для этого здесь.

Предыдущий ответ уже говорил вам о #include <memory>; в последующем вы утверждаете, что основной пример не работает - он работает для меня.

Но первое уточнение: все управление памятью через вызовы добавленных (скомпилированных) функций должно осуществляться через управление памятью R. Это то, что делает Rcpp, и что Rcpp документирует. Теперь для многопоточного кода мы имеем RMatrix а также RVector в RcppParalllel, потому что мы не можем вмешиваться в управление памятью R (и его однопоточный режим) из многопоточного кода; подробности смотрите в превосходной документации RcppParallel.

Тем не менее, если вы уверены, что хотите shared_ptr в пределах определенной области вы можете. Вот рабочая копия, основанная на приведенном вами примере.

Код

#include <memory>
#include <Rcpp.h>

// [[Rcpp::plugins(cpp11)]]

struct C { int* data; };

// [[Rcpp::export]]
bool foo() {
   std::shared_ptr<int> p1;
   std::shared_ptr<int> p2 (nullptr);
   std::shared_ptr<int> p3 (new int);
   std::shared_ptr<int> p4 (new int, std::default_delete<int>());
   std::shared_ptr<int> p5 (new int, [](int* p){delete p;}, std::allocator<int>());
   std::shared_ptr<int> p6 (p5);
   std::shared_ptr<int> p7 (std::move(p6));
   std::shared_ptr<int> p8 (std::unique_ptr<int>(new int));
   std::shared_ptr<C> obj (new C);
   std::shared_ptr<int> p9 (obj, obj->data);

   Rcpp::Rcout << "use_count:\n";
   Rcpp::Rcout << "p1: " << p1.use_count() << '\n';
   Rcpp::Rcout << "p2: " << p2.use_count() << '\n';
   Rcpp::Rcout << "p3: " << p3.use_count() << '\n';
   Rcpp::Rcout << "p4: " << p4.use_count() << '\n';
   Rcpp::Rcout << "p5: " << p5.use_count() << '\n';
   Rcpp::Rcout << "p6: " << p6.use_count() << '\n';
   Rcpp::Rcout << "p7: " << p7.use_count() << '\n';
   Rcpp::Rcout << "p8: " << p8.use_count() << '\n';
   Rcpp::Rcout << "p9: " << p9.use_count() << '\n';

   return true;
}

использование

R> Rcpp::sourceCpp("/tmp/soExample.cpp")
R> foo()
use_count:
p1: 0
p2: 0
p3: 1
p4: 1
p5: 2
p6: 0
p7: 2
p8: 1
p9: 2
[1] TRUE
R> 
Другие вопросы по тегам