#rcpp
#rcpp
Вопрос:
Мне было интересно, как я мог бы заставить некоторый код Rcpp использовать автоматическую защиту от разматывания во всех объектах Rcpp.
Например, предположим, что у меня есть такой код:
#include <stdint.h>
#include <Rcpp.h>
class MyObj {
public:
int val;
MyObj(int val) : val(val) {};
~MyObj() {
std::cout << "I' being destructed - value was: " << val << std::endl;
}
};
// [[Rcpp::export]]
Rcpp::NumericVector crashme(unsigned int seed)
{
srand(seed);
MyObj obj1(rand());
Rcpp::NumericVector out(INT64_MAX-1, 100.);
return out;
}
Когда я вызываю crashme
, obj1
не уничтожается до завершения функции из-за длинных переходов R, от которых я хочу защитить.
Я вижу, что есть функция Rcpp::unwindProtect
, но она реализована как нечто, требующее обратного вызова.
Я не уверен на 100%, правильно ли я все делаю, но мне удалось добавить защиту от разматывания следующим образом:
#include <stdint.h>
#include <Rcpp.h>
#include <Rcpp/unwindProtect.h>
// [[Rcpp::plugins(unwindProtect)]]
class MyObj {
public:
int val;
MyObj(int val) : val(val) {};
~MyObj() {
std::cout << "I' being destructed - value was: " << val << std::endl;
}
};
struct NumVecArgs {
size_t size;
double fillwith;
};
SEXP alloc_NumVec(void *data)
{
NumVecArgs *args = (NumVecArgs*)data;
return Rcpp::NumericVector(args->size, args->fillwith);
}
// [[Rcpp::export]]
Rcpp::NumericVector crashme(unsigned int seed)
{
srand(seed);
MyObj obj1(rand());
NumVecArgs args = {INT64_MAX-1, 100.};
Rcpp::NumericVector out = Rcpp::unwindProtect(alloc_NumVec, (void*)amp;args);
return out;
}
Теперь вызов crashme
будет успешно уничтожен obj1
и выведет сообщение деструктора.
Но это очень неудобно, поскольку у меня есть ряд различных распределений объектов Rcpp, использующих разные типы конструкторов, что подразумевает либо определение другой структуры и обратного вызова для каждого из них, либо перевод всех вызовов в длинные лямбда-функции.
Есть ли какой-либо способ автоматически выполнять все вызовы конструкторов, например Rcpp::NumericVector
, и Rcpp::IntegerVector
иметь защиту от разматывания?