Pybind11 и несогласованные типы, выведенные для лямбда-выражения

#python #c #lambda #pybind11

#python #c #лямбда #pybind11

Вопрос:

В коде cpp, который я не могу изменить, у нас есть пользовательский класс и пользовательские указатели. Этот класс считывает объект и в зависимости от kwargs может также записать его. Мне нужно сделать для него привязки pybind11.

В зависимости от переданных аргументов мы получаем константный или неконстантный указатель на класс. Pybind жалуется на несовместимые типы для возвращаемого типа lambda. Все это хорошо подходит для создания init() функции, которая работает только для константных или неконстантных объектов. К сожалению, необходимо поддерживать оба случая. Каков наилучший способ сделать привязку python к cpp-коду в этом случае?

Ошибка

 In lambda function:
error: inconsistent types 'std::shared_ptr<myClass>' and 'std::shared_ptr<const myClass>'
deduced for lambda return type
  return *const_p;
 

Как можно изменить приведенный ниже код для поддержки обоих случаев?
С использованием компилятора Cpp 11.

 // those defined elsewhere
typedef std::shared_ptr< myClass > my_ptr;
typedef std::shared_ptr< const myClass > const_my_ptr;

//init function for pybind11
.def(py::init([](py::kwargs kwargs) {
    bool object_writable = py::bool_(kwargs["rw"]);
    int cache = py::bool_(kwargs["cache"]);
    std::string path = py::str(kwargs["path"]);
    if (object_writable){
        //returns non const
        my_ptr p = myClass::read_write(path)
        return *p;
    }
    else{
        //returns const
        const_my_ptr const_p = myClass::read(path, cache)
        return *const_p;
    }
}))
 

Комментарии:

1. Ошибка не имеет ничего общего с pybind11, вы пытаетесь определить лямбда-выражение с двумя разными типами возвращаемых значений, а именно std::shared_ptr<myClass> и std::shared_ptr<const myClass> , что просто недопустимо, поскольку один возвращаемый тип должен быть известен во время компиляции.

2. Если я не ошибаюсь, есть еще одна не связанная с вашим кодом проблема: вы создаете указатель на std::shared_ptr , а лямбда-выражение возвращает его копию, то есть происходит утечка памяти. Что еще хуже, поскольку вы пропускаете a std::shared_ptr , количество ссылок на общий объект никогда не будет равно нулю, и он не будет удален автоматически. Вы можете напрямую назначить my_ptr p = myClass::read_write(path) и. const_my_ptr const_p = myClass::read(path, cache) Я не очень хорошо знаком с pybind, но я надеюсь, что это все же немного поможет найти рабочее решение.

3. Да, сообщение об ошибке довольно четкое. Вопрос в том, как создать правильную привязку с помощью pybind11. Вопрос не в том, как заставить этот код компилироваться. Спасибо за комментарий, обновил вопрос с большей ясностью.

4. Разве вы не можете просто попытаться скопировать const myClass в неконстантный объект (если конструктор копирования завершает работу), т. Е. return std::make_shared<myClass>(*const_p) Для случая else?

5. Верно, это, вероятно, лучшее, что можно сделать.