首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Boost Python未找到std::string的to_python转换器

Boost Python未找到std::string的to_python转换器
EN

Stack Overflow用户
提问于 2011-06-08 14:08:02
回答 2查看 3.2K关注 0票数 17

因此,我正在尝试创建一个to_python转换器,它允许我从公开的函数返回boost::optional,如果设置了optional,则将其视为T,如果未设置,则将其视为None。基于我在C++Sig上找到的一篇文章,我写了以下代码。

代码语言:javascript
复制
template<typename T>
struct optional_ : private boost::noncopyable {
  struct conversion {
    static PyObject* convert(boost::optional<T> const& value) {
      if (value) {
        return boost::python::to_python_value<T>()(*value);
      }
      Py_INCREF(Py_None);
      return Py_None;
    }
  };
  explicit optional_() {
    boost::python::to_python_converter<boost::optional<T>, conversion>();
  }
};

据我所知,它适用于转换可选参数,但python抛出了以下异常:"TypeError:找不到适用于C++类型的字符串(按值)转换器: std::string“。我知道C++能够将字符串转换为python,因为我公开的大多数函数都返回字符串。为什么boost::python::to_python_value不能识别它,我如何利用它拥有的任何转换器?

已通过更改为以下内容进行修复(基于this article):

代码语言:javascript
复制
template<typename T>
struct optional_ : private boost::noncopyable {
  struct conversion {
    static PyObject* convert(boost::optional<T> const& value) {
      using namespace boost::python;
      return incref((value ? object(*value) : object()).ptr());
    }
  };
  explicit optional_() {
    boost::python::to_python_converter<boost::optional<T>, conversion>();
  }
};

现在只需要做另一个版本,这样它就更干净,效果更好。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-07-23 02:33:44

好的,这里是整个可选的to和from转换器,基于最初的C++签名帖子,但重写为使用高级boost.python API (抱歉,空格太奇怪)。

代码语言:javascript
复制
template<typename T>
struct optional_ : private boost::noncopyable
{
  struct conversion :
    public boost::python::converter::expected_from_python_type<T>
  {
    static PyObject* convert(boost::optional<T> const& value) {
      using namespace boost::python;
      return incref((value ? object(*value) : object()).ptr());
    }
  };

  static void* convertible(PyObject *obj) {
    using namespace boost::python;
    return obj == Py_None || extract<T>(obj).check() ? obj : NULL;
  }

  static void constructor(PyObject *obj,
       boost::python::converter::rvalue_from_python_stage1_data *data)
  {
    using namespace boost::python;
    void *const storage =
      reinterpret_cast<
        converter::rvalue_from_python_storage<boost::optional<T> >*
      >(data)->storage.bytes;
    if(obj == Py_None) {
      new (storage) boost::optional<T>();
    } else {
      new (storage) boost::optional<T>(extract<T>(obj));
    }
    data->convertible = storage;
  }

  explicit optional_() {
    using namespace boost::python;
    if(!extract<boost::optional<T> >(object()).check()) {
      to_python_converter<boost::optional<T>, conversion, true>();
      converter::registry::push_back(
        &convertible,
        &constructor,
        type_id<boost::optional<T> >(),
        &conversion::get_pytype
      );
    }
  }
};
票数 4
EN

Stack Overflow用户

发布于 2015-02-19 18:59:02

上面的代码中有几个拼写错误-以下是更正后的版本:

代码语言:javascript
复制
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <boost/python.hpp>

template<typename T>
struct python_optional : private boost::noncopyable {
  struct conversion : public boost::python::converter::expected_from_python_type<T>
  {
    static PyObject* convert(boost::optional<T> const& value)
    {
      using namespace boost::python;
      return incref((value ? object(*value) : object()).ptr());
    }
  };

  static void* convertible(PyObject *obj) {
    using namespace boost::python;
    return obj == Py_None || extract<T>(obj).check() ? obj : NULL;
  }

  static void constructor(
    PyObject *obj,
    boost::python::converter::rvalue_from_python_stage1_data *data
  ) {
    using namespace boost::python;
    void *const storage =
      reinterpret_cast<
        converter::rvalue_from_python_storage<boost::optional<T> >*
      >(data)->storage.bytes;
    if(obj == Py_None) {
      new (storage) boost::optional<T>();
    } else {
      new (storage) boost::optional<T>(extract<T>(obj));
    }
    data->convertible = storage;
  }

  explicit python_optional() {
    using namespace boost::python;
    if(!extract<boost::optional<T> >(object()).check()) {
      to_python_converter<boost::optional<T>, conversion, true>();
      converter::registry::push_back(
        &convertible,
        &constructor,
        type_id<boost::optional<T> >(),
        &conversion::get_pytype
      );
    }
  }
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6274822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档