Rcpp 需要复制构造函数
Rcpp requires a copy constructor
我正在尝试使用 Rcpp 将一些 C++11 功能导出到 R。其中一些函数 return 它们的结果使用 std::unique_ptr
。这东西是抄不来的。下面的 MCVE 使用 std::unique_ptr<std::string>
来说明错误。
我围绕 unique_ptr
创建了一个 class,希望让这一切成为可能,但无济于事。这是下面的PtrClassOwner
。函数 createClassWrapper
调用原始 createClass
,将 unique_ptr
粘贴到 PtrClassOwner
对象中。
#include <RcppCommon.h>
#include <memory>
#include <string>
// Stuff to wrap:
using PtrClass = std::unique_ptr<std::string>;
PtrClass createClass() { return PtrClass{new std::string("boo")}; }
// ---
class PtrClassOwner {
public:
PtrClass string;
};
PtrClassOwner createClassWrapper() { return PtrClassOwner{createClass()}; }
RCPP_EXPOSED_WRAP(PtrClassOwner); // Rcpp-extending vignette says RCPP_EXPORT_WRAP, which doesn't exist.
RCPP_EXPOSED_AS(PtrClassOwner);
#include <Rcpp.h>
RCPP_MODULE(Class){
using namespace Rcpp;
class_<PtrClassOwner>("PtrClass");
function("createClass", &createClassWrapper);
}
这是 GCC(v 5.4,在 Linux 上)报告的第一个错误:
In file included from /home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/RcppCommon.h:195:0,
from rcpp_module.cpp:1:
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h: In instantiation of ‘SEXPREC* Rcpp::internal::wrap_dispatch(const T&, Rcpp::traits::wrap_type_module_object_tag) [with T = PtrClassOwner; SEXP = SEXPREC*]’:
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap_end.h:30:38: required from ‘SEXPREC* Rcpp::wrap(const T&) [with T = PtrClassOwner; SEXP = SEXPREC*]’
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap_end.h:35:20: required from ‘SEXPREC* Rcpp::module_wrap_dispatch(const T&, Rcpp::traits::normal_wrap_tag) [with T = PtrClassOwner; SEXP = SEXPREC*]’
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:922:40: required from ‘SEXPREC* Rcpp::module_wrap(const T&) [with T = PtrClassOwner; SEXP = SEXPREC*]’
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/module/Module_generated_CppFunction.h:34:50: required from ‘SEXPREC* Rcpp::CppFunction0<RESULT_TYPE>::operator()(SEXPREC**) [with RESULT_TYPE = PtrClassOwner; SEXP = SEXPREC*]’
rcpp_module.cpp:26:1: required from here
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:759:54: error: use of deleted function ‘PtrClassOwner::PtrClassOwner(const PtrClassOwner&)’
return Rcpp::internal::make_new_object<T>(new T(object));
^
rcpp_module.cpp:9:7: note: ‘PtrClassOwner::PtrClassOwner(const PtrClassOwner&)’ is implicitly deleted because the default definition would be ill-formed:
class PtrClassOwner {
^
问题似乎是,要将对象包装到 R 对象中,需要复制它。 This other question 某人 运行 提出类似问题,但没有答案。
我创建了一个类似于 Python 的接口,其中 Python 对象只包含一个指向 C++ 对象的指针。我觉得很奇怪,Rcpp 试图复制对象来包装它。
有办法解决这个问题吗?是否有可能仅将指向对象的指针包装在 R 类型中,并且仍然以某种方式正确管理其生命周期?我对任何解决方案持开放态度,我不打算使用 Rcpp,它似乎是导出此功能的最直接方法。
到目前为止我发现的最简单的解决方案是从 std::unique_ptr
中提取指针并从中创建一个 std::shared_ptr
。 Rcpp 将包装它,因为它可以被复制。
#include <Rcpp.h>
#include <memory>
#include <string>
// Stuff to wrap:
using PtrClass = std::unique_ptr<std::string>;
PtrClass createClass() { return PtrClass{new std::string("boo")}; }
// ---
using ShPtrClass = std::shared_ptr<PtrClass::element_type>;
class PtrClassOwner {
public:
ShPtrClass shPtrClass;
PtrClassOwner(PtrClass ptr) : shPtrClass(ptr.release()) {}
};
PtrClassOwner createClassWrapper() { return PtrClassOwner{createClass()}; }
std::string getString(PtrClassOwner const& ptr) {
return *(ptr.shPtrClass);
}
RCPP_EXPOSED_CLASS(PtrClassOwner);
RCPP_MODULE(Class){
using namespace Rcpp;
class_<PtrClassOwner>("PtrClass");
function("createClass", &createClassWrapper, "createClass method");
function("getString", &getString, "getString method");
}
我正在尝试使用 Rcpp 将一些 C++11 功能导出到 R。其中一些函数 return 它们的结果使用 std::unique_ptr
。这东西是抄不来的。下面的 MCVE 使用 std::unique_ptr<std::string>
来说明错误。
我围绕 unique_ptr
创建了一个 class,希望让这一切成为可能,但无济于事。这是下面的PtrClassOwner
。函数 createClassWrapper
调用原始 createClass
,将 unique_ptr
粘贴到 PtrClassOwner
对象中。
#include <RcppCommon.h>
#include <memory>
#include <string>
// Stuff to wrap:
using PtrClass = std::unique_ptr<std::string>;
PtrClass createClass() { return PtrClass{new std::string("boo")}; }
// ---
class PtrClassOwner {
public:
PtrClass string;
};
PtrClassOwner createClassWrapper() { return PtrClassOwner{createClass()}; }
RCPP_EXPOSED_WRAP(PtrClassOwner); // Rcpp-extending vignette says RCPP_EXPORT_WRAP, which doesn't exist.
RCPP_EXPOSED_AS(PtrClassOwner);
#include <Rcpp.h>
RCPP_MODULE(Class){
using namespace Rcpp;
class_<PtrClassOwner>("PtrClass");
function("createClass", &createClassWrapper);
}
这是 GCC(v 5.4,在 Linux 上)报告的第一个错误:
In file included from /home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/RcppCommon.h:195:0,
from rcpp_module.cpp:1:
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h: In instantiation of ‘SEXPREC* Rcpp::internal::wrap_dispatch(const T&, Rcpp::traits::wrap_type_module_object_tag) [with T = PtrClassOwner; SEXP = SEXPREC*]’:
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap_end.h:30:38: required from ‘SEXPREC* Rcpp::wrap(const T&) [with T = PtrClassOwner; SEXP = SEXPREC*]’
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap_end.h:35:20: required from ‘SEXPREC* Rcpp::module_wrap_dispatch(const T&, Rcpp::traits::normal_wrap_tag) [with T = PtrClassOwner; SEXP = SEXPREC*]’
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:922:40: required from ‘SEXPREC* Rcpp::module_wrap(const T&) [with T = PtrClassOwner; SEXP = SEXPREC*]’
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/module/Module_generated_CppFunction.h:34:50: required from ‘SEXPREC* Rcpp::CppFunction0<RESULT_TYPE>::operator()(SEXPREC**) [with RESULT_TYPE = PtrClassOwner; SEXP = SEXPREC*]’
rcpp_module.cpp:26:1: required from here
/home/cris/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:759:54: error: use of deleted function ‘PtrClassOwner::PtrClassOwner(const PtrClassOwner&)’
return Rcpp::internal::make_new_object<T>(new T(object));
^
rcpp_module.cpp:9:7: note: ‘PtrClassOwner::PtrClassOwner(const PtrClassOwner&)’ is implicitly deleted because the default definition would be ill-formed:
class PtrClassOwner {
^
问题似乎是,要将对象包装到 R 对象中,需要复制它。 This other question 某人 运行 提出类似问题,但没有答案。
我创建了一个类似于 Python 的接口,其中 Python 对象只包含一个指向 C++ 对象的指针。我觉得很奇怪,Rcpp 试图复制对象来包装它。
有办法解决这个问题吗?是否有可能仅将指向对象的指针包装在 R 类型中,并且仍然以某种方式正确管理其生命周期?我对任何解决方案持开放态度,我不打算使用 Rcpp,它似乎是导出此功能的最直接方法。
到目前为止我发现的最简单的解决方案是从 std::unique_ptr
中提取指针并从中创建一个 std::shared_ptr
。 Rcpp 将包装它,因为它可以被复制。
#include <Rcpp.h>
#include <memory>
#include <string>
// Stuff to wrap:
using PtrClass = std::unique_ptr<std::string>;
PtrClass createClass() { return PtrClass{new std::string("boo")}; }
// ---
using ShPtrClass = std::shared_ptr<PtrClass::element_type>;
class PtrClassOwner {
public:
ShPtrClass shPtrClass;
PtrClassOwner(PtrClass ptr) : shPtrClass(ptr.release()) {}
};
PtrClassOwner createClassWrapper() { return PtrClassOwner{createClass()}; }
std::string getString(PtrClassOwner const& ptr) {
return *(ptr.shPtrClass);
}
RCPP_EXPOSED_CLASS(PtrClassOwner);
RCPP_MODULE(Class){
using namespace Rcpp;
class_<PtrClassOwner>("PtrClass");
function("createClass", &createClassWrapper, "createClass method");
function("getString", &getString, "getString method");
}