1

I'm trying to bind a registerHandler() defined in a given class, which I can't modify.

The class:

class FG{
public: 
    
    //return DType, no input argument
    using Handler = std::function<DType(void)>;

    void RegisterHandler(Handler h);
}

class DType{
public:
    DType() noexcept = default;
    DType(DType const &) = delete;
    DType(DType&& other) noexcept = default;
    ~DType() noexcept
   {...
   }
   DType& operator=(DType const&) = delete;
   DType& operator=(DType&& other) & noexcept = default;
   ...
}

If I bind it like below, it gives an error message saying "error: use of deleted function 'DType(const DType&)'.

#include <pybind/pybind11>
#include <pybind/stl_bind11>
#include <pybind/functional.h>
#include <pybind/stl.h>

using Handler = std::function<DType>(void);

void bind_FG(py::module& m)
{
  py::class_<FG> pyClass(m, "FG", py::module_local());
  pyClass.def("RegisterHandler" &RegisterHandler);

//or 
//  pyClass.def("RegisterHandler", [](FG& self, Handler h)
//              {
//                self.RegisterHandler(h);
//              }
//             );

}

I googled std::function, and it says it requires a copy ctor, does it mean that there is no way to bind the RegisterHandler() for my case?

At the same time, I'm confused we have implemented the handler function in the C++ side, it seems to be fine (build and work). Why doesn't it require a copy ctor for C++ code?

James Z
  • 12,209
  • 10
  • 24
  • 44
  • Still unclear to me how did you get `error: use of deleted function 'DType(const DType&)`, because in your example I don't see any copy. Anyway, documentation says that the function/functor itself must be copyconstructible, accepting non-copyconstructible arguments by const ref is fine. – pptaszni Jul 07 '22 at 16:25
  • OK, indeed I can reproduce this problem. I have a workaround, if you can modify the `Handler` definition a little bit. If instead of `std::function` declare `struct Handler { DType operator() (); };` then it will be possible to bind the `operator()` like this `py::class_(m, "Handler").def("__call__", [](Handler& h) { return h(); });`, and `RegisterHandler` like you did before. Otherwise, no idea. – pptaszni Jul 08 '22 at 10:51

0 Answers0