1

I want to bind a function that takes a lambda (std::function) as an argument. The lambda itself has a reference to an abstract type as an argument. When I attempt to invoke the function in python, I get an error because the abstract type is not copyable.

Below is a small example. I have an interface IFoo which is abstract and its concrete implementation Foo. I then have a function evaluate which takes as an argument a std::function<void(IFoo&)>.

I would prefer not to expose the concrete implementation in the python binding so I only bind the interface.

#include <iostream>

#include <pybind11/pybind11.h>
#include <pybind11/functional.h>

namespace py = pybind11;

class IFoo
{
public:
    virtual ~IFoo() = default;
    virtual void setValue(int a) = 0;
};

class Foo : public IFoo
{
public:
    ~Foo() override = default;

    void setValue(int a) override { m_a = a; }
    int getValue() const { return m_a; }
protected:
    int m_a{18};
};

int evaluate(std::function<void(IFoo&)>&& callback)
{
    Foo foo;
    callback(foo);
    return foo.getValue() + 34;
}

PYBIND11_MODULE(libbindtest, module)
{
    py::class_< IFoo >(module, "Foo").def("setValue", &IFoo::setValue);
    module.def("evaluate", &evaluate);
}

/*
int main (int, char**)
{
    int res1 = evaluate([](auto& foo){ foo.setValue(22); });
    int res2 = evaluate([](auto&){});
    std::cout << "Res1: " << res1 << " Res2: " << res2 << std::endl;
    return 0;
}
*/

This builds fine and runs with this definition of main.

My python looks like

import libbindtest as bt

def foo_operator(foo: bt.Foo):
    foo.setValue(22)

x = bt.evaluate(foo_operator)

With this, I get the error

Traceback (most recent call last):
  File "/path/to/bindtest.py", line 6, in <module>
    x = bt.evaluate(foo_operator)
RuntimeError: return_value_policy = copy, but type IFoo is non-copyable!

I don't understand why IFoo needs to be copyable here. If I change the function definition to

int evaluate(std::function<void(IFoo*)>&& callback)

then everything works fine. Does someone know what I'm missing here.

1
  • Probably related to this Commented Jul 29 at 10:19

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.