2013-07-29 8 views
3

Я экспериментировал с универсальными ссылками C++ 11 и совершенной пересылкой в ​​некоторых классах, к которым также нужно обращаться с Python с помощью Boost.Python. У меня есть код, который работает, но он требует некоторой уродливой специализации шаблона вне класса. Кто-нибудь решил это более элегантно? Есть ли у кого-нибудь предложения по улучшению следующего кода?Boost.python с универсальной ссылкой/идеальной пересылкой?

#include <boost/python.hpp> 
#include <string> 

using namespace boost::python; 

struct A { 
    A() : _a("initial") {} 

    template <typename T> 
    void set_a(T&& a) { _a = std::forward<T>(a); } 

    const std::string& get_a() const { return _a; } 

private: 
    std::string _a; 
}; 

// How can the following template member function specialization be avoided? 
template <> 
void A::set_a(const std::string& a) { _a = a; } 

BOOST_PYTHON_MODULE(example) 
{ 
    class_<A>("A") 
     .add_property("a", make_function(&A::get_a, return_value_policy<copy_const_reference>()), 
        &A::set_a<const std::string&>) // Can this be defined differently? 
    ; 
} 
+0

что вы надеетесь получить от совершенной переадресации в этом случае? сохрани копию? ваша специализация эффективно полностью исключает вашу функцию переадресации от вызова. – nijansen

+0

Да, я стараюсь избегать ненужного создания временных объектов со стороны C++ и избегать копирования. На стороне C++ эквивалент стороны set_a() может вызываться с помощью Rvalues, Lvalues ​​и строковых литералов. Производительность очень важна в этих путях. При вызове из Python производительность не входит в какой-либо тип пути производительности, но требуется доступ к некоторым объектам. Код примера, вероятно, неверно подразумевает, что я пытаюсь избежать копирования из кода Python, но это не мое намерение. – jhand

ответ

1

Я экспериментировал сегодня и нашел ответ на самом деле довольно простым. Просто используйте make_function() снова в SETR части add_property:

Вот упрощенный код:

#include <boost/python.hpp> 
#include <string> 

using namespace boost::python; 

struct A { 
    A() : _a("initial") {} 

    template <typename T> 
    void set_a(T&& a) { _a = std::forward<T>(a); } 

    const std::string& get_a() const { return _a; } 

private: 
    std::string _a; 
}; 

BOOST_PYTHON_MODULE(example) 
{ 
    class_<A>("A") 
     .add_property("value", 
        make_function(&A::get_a, return_value_policy<copy_const_reference>()), 
        make_function(&A::set_a<const std::string&>) 
    ); 
} 

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

  • Нет связанных вопросов^_^