Skip to content

Not possible to return unique pointer to pure virtual class #641

@Munken

Description

@Munken

If I try to return a unique pointer to a pure virtual class it fails due to

return_value_policy = move, but the object is neither movable nor copyable!

However it if the class is not pure virtual it works fine. Same for returning a shared pointer to it.

Below is a minimal working example based on the docs

#include <pybind11/pybind11.h>
namespace py = pybind11;

class Animal {
public:
    virtual ~Animal() { }
    virtual std::string go(int n_times) = 0;
};

class Dog : public Animal {
public:
    std::string go(int n_times) override {
        std::string result;
        for (int i=0; i<n_times; ++i)
            result += "woof! ";
        return result;
    }
};

class PyAnimal : public Animal {
public:
    /* Inherit the constructors */
    using Animal::Animal;

    /* Trampoline (need one for each virtual function) */
    std::string go(int n_times) override {
        PYBIND11_OVERLOAD_PURE(
                std::string, /* Return type */
                Animal,      /* Parent class */
                go,          /* Name of function in C++ (must match Python name) */
                n_times      /* Argument(s) */
        );
    }
};

std::unique_ptr<Animal> build_dog() {
    return std::unique_ptr<Animal>(new Dog{});
}

std::shared_ptr<Animal> build_shared_dog() {
    return std::shared_ptr<Animal>(new Dog{});
}

PYBIND11_PLUGIN(PyAUSA) {


    py::module m("PyAUSA", "Python bindings for AUSAlib");

    py::class_<Animal, PyAnimal /* <--- trampoline*/> animal(m, "Animal");
    animal
            .def(py::init<>())
            .def("go", &Animal::go);

    py::class_<Dog>(m, "Dog", animal)
            .def(py::init<>());

    m.def("build_dog", &build_dog);
    m.def("build_shared_dog", &build_shared_dog);

    return m.ptr();
}

Output:

In [1]: import PyAUSA

In [2]: PyAUSA.build_shared_dog()
Out[2]: <PyAUSA.Dog at 0x7fab45d1d7e0>

In [3]: PyAUSA.build_dog()
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-3-d86cdac6dbbe> in <module>()
----> 1 PyAUSA.build_dog()

RuntimeError: return_value_policy = move, but the object is neither movable nor copyable!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions