Pybind - вызывать функцию с Shared-Pointer для производного класса - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть следующие настройки (1 Базовый класс, 1 Производный класс, 1 Контейнер).Контейнер принимает shared_ptr<Base> в качестве ввода.

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

struct Base { };
struct Derived : public Base { };

struct Container { void input(const std::shared_ptr<Base>& ptr) { } };

PYBIND11_MODULE(PybindTest, m)
{
    py::class_<Base,    std::shared_ptr<Base>>(m, "Base").def(py::init<>());
    py::class_<Derived, std::shared_ptr<Derived>>(m, "Derived").def(py::init<>());

    py::class_<Container, std::shared_ptr<Container>>(m, "Container")
        .def(py::init<>())
        .def("input", &Container::input);
}

В C ++ я могу передать либо shared_ptr<Base>, либо shared_ptr<Derived> в функцию input.Но в Python я получаю сообщение об ошибке:

import PybindTest as p
p.Container().input(p.Base())      # All good
p.Container().input(p.Derived())   # Throws Error

# TypeError                                 Traceback (most recent call last)
# <ipython-input-10-70fe5b9f3a41> in <module>
#       1 import PybindTest as p
#       2 p.Container().input(p.Base())
# ----> 3 p.Container().input(p.Derived())
# 
# TypeError: input(): incompatible function arguments. The following argument types are supported:
#     1. (self: PybindTest.Container, arg0: PybindTest.Base) -> None
# 
# Invoked with: <PybindTest.Container object at 0x0000022378B4FF80>, <PybindTest.Derived object at 0x0000022378B4FCE0>

Я пытался поиграться с такими вещами, как

.def("input", py::overload_cast<const std::shared_ptr<Derived>&> (&Container::input))
.def("input", [](const std::shared_ptr<Derived> & ptr) { this->input(ptr); })

, но ни один из этих двух компилируется. Любой совет?

Я использую Windows 10 с Python 3.6 x64 и компилирую все с VS 2019.

1 Ответ

0 голосов
/ 23 февраля 2019

Как предложено @nm:

py::class_<Derived, std::shared_ptr<Derived>, Base>(m, "Derived")
    .def(py::init<>());

Из документации по pybind11 (Метод 1: параметр шаблона)

...