2013-07-29 6 views
3

저는 Boost.Python을 사용하여 파이썬에서 액세스해야하는 일부 클래스에서 C++ 11 범용 참조 및 완벽한 전달을 실험 해 왔습니다. 작동하는 코드를 가지고 있지만 클래스 외부에서 추악한 템플릿 전문화가 필요합니다. 아무도 이것을보다 우아한 방식으로 해결 했습니까? 누구나 다음 코드를 개선하기위한 제안 사항이 있습니까?범용 참조/완벽한 전달 기능을 갖춘 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++ 측에서는 Rvalues, Lvalues ​​및 문자열 리터럴을 사용하여 set_a()면과 동일한 함수를 호출 할 수 있습니다. 성능은 이러한 경로에서 매우 중요합니다. 파이썬에서 호출 할 때 성능은 어떤 유형의 성능 경로도 아니지만 일부 객체에 대한 액세스가 필요합니다. 예제 코드는 아마도 Python 코드의 복사본을 피하려고 시도하고 있음을 의미하는 것은 아닙니다. 그러나 이것은 내 의도가 아닙니다. – jhand

답변

1

나는 약간의 실험을했으며 실제로 대답이 매우 간단하다는 것을 알았습니다.

다음

이 단순화 된 코드입니다 : 그냥 add_property의 setr 부분에 다시) make_function를 (사용

#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&>) 
    ); 
} 
관련 문제