问题
I would like to use a threadsafe function pointer to be applied in an RcppPrallel worker. But I have already problems with this tiny example. No matter if I use it in a package and add SystemRequirements: C++11
in the DESCRIPTION file, or use it in a standard cpp file and add // [[Rcpp::plugins(cpp11)]]
I get the same Errors: 'shared_ptr' is not a member of 'std'. Can anyone please help me? Thank you!
#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")
}
*/
System information:
> 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
回答1:
std::shared_ptr
is declared in the header <memory>
. Try:
#include <memory>
You can find the documentation for it here.
回答2:
The previous answer already told you about #include <memory>
; in the follow-up you claim the basic example does not work -- it does for me.
But one clarification first: all memory management across calls to added (compiled) functions has to happen via R's memory management. That is what Rcpp does, and what Rcpp documents. Now, for multithreaded code we have RMatrix
and RVector
in RcppParalllel because we cannot interfere with R's memory management (and its single-threaded mode) from multithreaded code; see RcppParallel's excellent documentation for details.
That said, if you are sure you want shared_ptr
within defined scope, you can. Here is a working copy based on the example you linked too.
Code
#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;
}
Use
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>
来源:https://stackoverflow.com/questions/51481236/threadsafe-function-pointer-with-rcpp-and-rcppparallel-via-stdshared-ptr