c++ - Rcpp 需要复制构造函数

标签 c++ c++11 rcpp

我正在尝试使用 Rcpp 将一些 C++11 功能导出到 R。其中一些函数使用std::unique_ptr返回其结果。 。这个东西是无法复制的。下面的 MCVE 使用 std::unique_ptr<std::string>来说明错误。

我围绕 unique_ptr 创建了一个类,希望使这一切成为可能,但无济于事。这是PtrClassOwner以下。函数createClassWrapper来电原createClass ,粘贴unique_ptrPtrClassOwner对象。

#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 类似的接口(interface),其中 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");
}

关于c++ - Rcpp 需要复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49785379/

相关文章:

c++ - if(null) 正在使用 clang++ 编译的特定计算机中执行

c++ - 为什么我的中断被调用,但不会进入处理程序?

c++ - 使用 Code::Blocks 编写的 SimpleSocket 对 C++ 程序中函数的 undefined reference

r - 在 R/Rcpp 中转置列表的最快方法

c++ - 如何通过 Rcpp 在 C++ 中使用 Boost 库

c++ - 在 R 包中构建和链接共享库 - 代码编译、链接,但不会加载

c++ - OpenSSL 使用 Cmake 从源代码编译?

c++ - 您如何重新分配(也称为集合)unique_ptr 类成员?

c++ - 为什么功能tellg()没有返回好的结果?

c++ - 使用 CPU 缓存行击败二进制搜索