2013-03-01 1 views
1

Я подвергал некоторые классы C++ Python, вложенные в enum. Посмотрев примерную документацию на boost.org и wiki.python.org, я не вижу, как оставить область действия после ее ввода, чтобы вернуться в область глобального/модуля. Вместо этого каждая последующая область становится вложенной в предыдущую.Boost.Python - Как повторно ввести область модуля?

В качестве примера:

#include <boost/python.hpp> 

class Foo 
{ 
public: 
    enum Choose { eFoo, eBar }; 

    /* Default constructor with enum as required argument */ 
    Foo(Choose choice): m_choice(choice) {} 
    ~Foo() {} 

    Choose get() const { return m_choice; } 

private: 
    const Choose m_choice; 

}; 


class Bar 
{ 
}; 

BOOST_PYTHON_MODULE(foo) 
{ 
    using namespace boost::python; 
    scope global; 

    /* Define Foo class, and a scope to go with it. */ 
    scope in_Foo = class_<Foo> 
     ("Foo", init<Foo::Choose>()) 
     .def("rovalue", &Foo::get) 
     ; 

    /* Expose 'Choose' enum as Foo.Choose */ 
    enum_<Foo::Choose>("Choose") 
     .value("Foo", Foo::eFoo) 
     .value("Bar", Foo::eBar) 
     ; 

    /* How to get back to module scope?? */ 
    global; 
    scope(); 

    /* This currently is exposed as Foo.Bar, but should just be Bar */ 
    class_<Bar>("Bar", init<>()) 
     ; 
} 

Я попытался изменить это global; линии различных вещей, но все к тому же результату:

$ g++ -fPIC -shared scope.cpp -o foo.so -lpython2.7 -I/usr/include/python2.7 -lboost_python 
$ python -c 'import foo; print "Bar" in dir(foo)' 
False 
$ python -c 'import foo; print "Bar" in dir(foo.Foo)' 
True 

EDIT:

Имея имел еще один взгляд на wiki.python.org, казалось бы, в приведенном выше примере правильным ответом было бы использовать scope within(global), чтобы вернуться к области уровня модуля. Действительно, это работает для приведенного выше примера. Однако, к сожалению, я получаю ошибку компиляции, когда я использую его в моем фактическом применении ..

#include <boost/python.hpp> 
using namespace boost; 
BOOST_PYTHON_MODULE(foo) 
{ 
    python::scope module_level; 
    /* .... */ 
    python::scope python::within(module_level); 
    /* ... */ 
} 

Ошибка компиляции:

error: invalid use of qualified-name 'boost::python::within' 

ответ

5

Как ни странно, и, возможно, слишком умна для своего собственного блага, это может быть достигнуто используя область C++. Документация boost::python::scope гласит, что когда время жизни объекта scope заканчивается, текущий объем возвращается к тому, что он был до того, как был создан объект scope.

BOOST_PYTHON_MODULE(foo)    // set scope to foo 
{ 
    using namespace boost::python; 
    { 
    scope in_Foo = class_<Foo>  // define foo.Foo and set scope to foo.Foo 
     ("Foo", init<Foo::Choose>()) 
     .def("rovalue", &Foo::get) 
     ; 

    enum_<Foo::Choose>("Choose")  // define foo.Foo.Choose 
     .value("Foo", Foo::eFoo) 
     .value("Bar", Foo::eBar) 
     ; 
    }         // revert scope, setting scope to foo 

    class_<Bar>("Bar", init<>())  // define foo.Bar 
     ; 
} 

Хотя scope объектов могли бы их жизнь удались с помощью других средств, я считаю, что использование scope объектов как автоматические переменные в пределах области C++ обеспечивает некоторый параллелизм пространств имен C++.

+0

Спасибо! Я по-прежнему новичок в C++, поэтому все еще нужно ухватить многие из этих хитрых функций языка. Это работает хорошо и, как ожидалось, хотя! –

+0

Меньше «По иронии судьбы, и, возможно, слишком умный» и более «это точно цель этого объекта». – Barry

Смежные вопросы