Перечисление с охватом класса

У меня есть класс С++ с enum внутри, и я хотел подражать этому с помощью boost::python, чтобы я мог писать MyClass.value в python. boost::python::class_ не имеет метода enum_, и я искал обходные пути.

  • Сначала я попытался использовать lambdas, например

    MyClass{
        enum{value1,value2};
    };
    
    class_<MyClass>("MyClass").add_property("value1",&[](){return value1;}).staticmethod("value1");
    

    который дает ошибку компилятора (в get_signature для add_property). Я знаю, что я мог бы создать метод getter для каждого из значений, но мне это кажется очень неудобным (типичным).

  • Использование attr:

    auto classObj=class_<MyClass>("MyClass");
    classObj.attr("value1")=(int)value1;
    classObj.attr("value2")=(int)value2;
    

    но он не может быть привязан как .def и другие методы, возвращающие ссылку на экземпляр.

Есть ли более элегантное решение?

Ответы

Ответ 1

Вы можете сделать это, используя область действия:

#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/scope.hpp>
#include <boost/python/enum.hpp>

namespace bp = boost::python;

class MyClass{
    public:
        enum MyEnum {value1,value2};
};

BOOST_PYTHON_MODULE(nestedtest){

    bp::scope the_scope
        = bp::class_<MyClass>("MyClass")
        ;

    bp::enum_<MyClass::MyEnum>("MyEnum")
        .value("value1", MyClass::value1)
        .value("value2", MyClass::value2)
        .export_values()
        ;
}

Затем в python ваши значения перечисления:

In [8]: nestedtest.MyClass.MyEnum.values
Out[8]: {0: nestedtest.MyEnum.value1, 1: nestedtest.MyEnum.value2}

In [9]: nestedtest.MyClass.MyEnum.value1
Out[9]: nestedtest.MyEnum.value1

In [10]: nestedtest.MyClass.MyEnum.value2
Out[10]: nestedtest.MyEnum.value2

(из моей оболочки ipython, я протестировал это и все;)