pybind11 - перенос перегруженного оператора присваивания?

Я использую pybind11 для предоставления функций C ++ интерфейсу Python. Я хочу обернуть перегруженный оператор присваивания, но не знаю, как это сделать. Представленная документация и примеры на самом деле не охватывают это, по крайней мере, из того, что я видел.

Вот упрощенная версия того, что я пытаюсь сделать:

class Num{
  public:
    Num(const double& num) : m_val(num), m_type(Num::Type::e_none){}

    Num& operator=(const double& rhs){m_val = rhs;}

  private:
    double m_val;
};

А вот упаковка:

PYBIND11_MODULE(demo, m){
    py::class_<Num>(m, "Num")
        .def(py::init<const double&>())
        // Overloaded assignment operator binding ?
        ;
}

Моя основная забота - сохранить тип данных Num при назначении его поплавку. например.:

>>> m = Num(4.5)
>>> type(m)
<class 'demo.Num'>
>>> m = 5.5
>>> type(m)
<class 'float'>

Я впервые работаю с расширениями и привязками C ++, поэтому любое понимание того, что мне следует делать, было бы здорово!


person adriyens    schedule 18.03.2020    source источник
comment
Это невозможно (хорошо, вы можете перехватить глобальный словарь __setitem__, но это ужасный взлом и очень хрупкий). Проблема в том, что Python использует присвоение ссылок, поэтому нет оператора присваивания, который можно было бы переопределить. Чтобы быть конкретным: это второе назначение удаляет старую ссылку на Num, а затем переназначает на 5.5. Ни в коем случае не задействован какой-либо метод Num. Альтернативой может быть, если все Num экземпляры живут в каком-то классе или модуле, тогда вы можете переопределить __setitem__ этого модуля / класса.   -  person Wim Lavrijsen    schedule 19.03.2020
comment
Ах я вижу. Таким образом, Python создает новый собственный объект типа bool, на который указывает имя m, вместо ранее созданного объекта Num. Я не заинтересован в том, чтобы возиться с какими-либо чертовыми функциями atm, но это определенно очень помогло. Спасибо!   -  person adriyens    schedule 01.04.2020


Ответы (1)


.def("assign", &Num::operator=);

См. https://github.com/pybind/pybind11/issues/250. Больше подробностей.

person Voya    schedule 05.09.2020
comment
Это работает только с определением функции Num & operator = (const Num &), поэтому нельзя управлять двойным воздействием. - person themadmax; 13.10.2020
comment
Вы можете сделать это: .def("assign", py::overload_cast<double>&Num::operator=); . При условии, что у вас есть оператор присваивания, который принимает двойное значение. или это: .def("assign", [](double value, Num& self){self = Num(value)});. - person plfoley; 20.11.2020