c++ - 使用 boost.python 返回内部引用的间歇性错误

标签 c++ boost c++11 boost-python

我有以下类(class):

#include <array>

template<unsigned short D>
class Point {
private:
    std::array<float, D> coordinates;
public:
    Point() { for(int i=D-1; i>=0; --i) coordinates[i] = 0.0; }
    Point(const Point& rhs) = default;
    Point& operator=(const Point& rhs) = default;
    ~Point() = default;

    float& get_ref(const unsigned short dimension)
        { return coordinates[dimension-1]; }
};

我正在尝试将其包裹起来:

#include <boost/python.hpp>

BOOST_PYTHON_MODULE(fernpy) {
    using namespace boost::python;

    class_< Point<2> >("point")
        .def("__call__", &Point<2>::get_ref, return_internal_reference<>());
}

我正在使用 gcc-4.7 为 Fedora 17 上的 boost 1.48 和 python-2.7 编译。所有代码都是一个名为 testpy.cpp 的文件。我正在使用这些命令进行编译:

g++ -std=c++11 -g -fPIC -I/usr/include/python2.7 -c testpy.cpp
g++ -shared -g -lpython2.7 -lboost_python -o libfern.so testpy.o

编译器返回一堆 boost 内部错误,太多了,无法在此处发布。这段摘录似乎是它的核心。前面有一堆“required from”,后面有“note”。

/usr/include/boost/python/object/make_instance.hpp:27:9: error: no matching function for call to ‘assertion_failed(mpl_::failed************ boost::mpl::or_<boost::is_class<float>, boost::is_union<float>, mpl_::bool_<false>, mpl_::bool_<false>, mpl_::bool_<false> >::************)’

如果我从 get_ref 返回一个普通的 float 并从包装器的 .def 行中删除 return_internal_reference<>() 参数,它就可以正常工作。这很奇怪,因为我正在用另一个更复杂的类模板做同样的事情,而且它在那里也工作得很好。我已经用谷歌搜索了将近一整天的时间来反对这个问题。任何人都知道到底发生了什么?

更新:

我最终使用了 python 中的“getitem”和“setitem”特殊方法,a la this link .该链接展示了如何使用用于访问函数的静态包装器定义漂亮的结构模板,这样您就不必弄乱原始 C++ 类的接口(interface)。

最佳答案

从 python 的角度来看,floats 是一种不可变类型。因此,python 不允许更改该值。

例如在python中出现如下情况:

coordinates = [ 5, 10, 15 ]
x = cooardinates[ 2 ] # Bind x to refer to the int(15) object.
x = 5                 # Rebind x to refer to the int(5) object. 
                      # Does not modify coordinates.

现在,考虑以下几点:

from fernpy import point
p = point()
x = p(2) # Bind x to refer to the float(p(2)) object.
x = 5    # Rebind x to refer to the int(5) object.
         # Does not set p.coordinates[2] to 5.

因此,boost::python 阻止返回对 python 中不可变类型的引用,因为 Python 不支持它。 x 不存储值 5;相反,它包含对 5 对象的引用。如果分配给 x 没有重新绑定(bind) x,则可能会出现无意义的语句,例如 6 = 5

编译错误是一种静态检查,它限制 return_internal_reference 仅适用于类或 union ,因为它们在 Python 中是可变类型。我想,起作用的“更复杂的类模板”正在返回对用户类型的引用。

关于c++ - 使用 boost.python 返回内部引用的间歇性错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11143634/

相关文章:

c++ - move 语义如何在 vector 重定位中起作用?

c++ - 模板类的可变成员函数

c++ - std::ofstream == NULL 不会为 -std=gnu++11 编译,任何解决方法?

c++ - Qt - 设置界面

c++ - C++ 程序如何为插入 (<<) 运算符选择正确的函数?

c++ - 面向任务的线程池

c++ - 使用 boost::program_options 来解析文本文件是个好主意吗?

c++ - Python distutils 拒绝识别已安装的 C++ 编译器,Python 3.5 下为 `Unable to find vcvarsall.bat`

c# - 从 C++ 应用程序 (Android NDK) 免费运行 C# 代码

c++ - 如何解码 boost 库命名?