首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法绑定成员函数中的右值引用参数

无法绑定成员函数中的右值引用参数
EN

Stack Overflow用户
提问于 2018-03-28 02:26:10
回答 1查看 757关注 0票数 2

我正在使用pybind11为一个不能更改其源代码的C++库创建python绑定。它包含一个用右值引用参数定义成员函数的类(例如T &&val)。我无法创建到具有右值引用参数的成员函数的绑定,但绑定到具有相同参数的非成员函数的工作方式与预期的一样。

一个简化的示例如下所示:

代码语言:javascript
复制
struct Foo {
    // Cannot create a pybinding for this method.
    void print_ref(int &&v) const {
            std::cout << "Foo::print_ref(" <<  to_string(v) << ")" <<std::endl;
    }
};
// Pybinding for standalone function works as expected.
void print_ref(int&& val) {
        std::cout << "print_ref(" << to_string(val) << ")" << std::endl;
};

pybind11代码如下所示:

代码语言:javascript
复制
PYBIND11_MODULE(refref, m) {
    py::class_<Foo>(m, "Foo")
    // Both of these attempts to create a pybinding FAILs with same error.
    .def("print_ref", &Foo::print_ref)
    .def("print_ref", (void (Foo::*) (int&&)) &Foo::print_ref);
    // This pybinding of standalone function is SUCCESSful.
    m.def("print_ref", &print_ref);
}

第一次尝试绑定时的编译错误为:

代码语言:javascript
复制
pybind11/bin/../include/site/python3.4/pybind11/pybind11.h:79:80: error: rvalue reference to type 'int' cannot bind to lvalue of type 'int'
        initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); },
                                                                               ^~~~
pybind11/bin/../include/site/python3.4/pybind11/pybind11.h:1085:22: note: in instantiation of function template specialization 'pybind11::cpp_function::cpp_function<void, Foo, int &&,
      pybind11::name, pybind11::is_method, pybind11::sibling>' requested here
        cpp_function cf(method_adaptor<type>(std::forward<Func>(f)), name(name_), is_method(*this),
                     ^
refref.cpp:31:3: note: in instantiation of function template specialization 'pybind11::class_<Foo>::def<void (Foo::*)(int &&) const>' requested here
        .def("print_ref", &Foo::print_ref);

你知道我可能做错了什么吗?因为它可以很好地处理非成员函数,所以我倾向于怀疑pybind11问题,但我想我应该先在这里检查一下。

EN

回答 1

Stack Overflow用户

发布于 2018-05-03 21:15:30

事实上,问题来自于rvalues。我从this SO answerthis blog post那里学到了很多东西。有一个很好的解决办法:您可以创建一个包装器类,它将把调用重定向到不能更改的C++库,并处理具有std::move语义的rvalue

代码语言:javascript
复制
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>

namespace py = pybind11;

struct Foo {
    void print_ref(int&& v) const {
            std::cout << "Foo::print_ref("  <<  +v << ")" <<std::endl;
    }
};


// This class will interface between PyBind and your library
class Foo_wrap{
private:
  Foo _mimu;
public:
  void print_ref(int v) const{
    _mimu.print_ref(std::move(v));
  }
};



PYBIND11_MODULE(example, m) {
     py::class_<Foo_wrap>(m, "Foo_wrap")
     .def(py::init())
     .def("print_ref", &Foo_wrap::print_ref);
}

您可以在Python中使用

代码语言:javascript
复制
import example as fo

wr = fo.Foo_wrap()
wr.print_ref(2)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49520017

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档