【问题标题】:Boost.python with universal reference / perfect forwarding?具有通用参考/完美转发的 Boost.python?
【发布时间】:2013-07-29 04:37:42
【问题描述】:

我一直在尝试使用 C++11 通用引用并在某些类中进行完美转发,这些类也需要使用 Boost.Python 从 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?
    ;
}

【问题讨论】:

  • 在这种情况下,您希望从完美转发中获得什么?保存副本?您的专业化有效地完全避免了您的转发功能被调用。
  • 是的,我试图避免从 C++ 端不必要地构造临时对象并避免复制。在 C++ 端,可以使用 Rvalues、Lvalues 和字符串文字调用 set_a() 端的等效项。性能在这些路径中非常重要。从 Python 调用时,性能不在任何类型的性能路径中,但需要访问某些对象。示例代码可能错误地暗示我试图避免复制 Python 代码,但这不是我的意图。

标签: c++ perfect-forwarding universal-reference


【解决方案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&> )
    );
}

【讨论】:

    猜你喜欢
    • 2015-10-03
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 2012-01-06
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多