间歇性的错误返回与Boost.Python的内部参考(intermittent error retu

2019-09-18 09:04发布

我有以下类:

#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编译升压1.48,蟒蛇 - 2.7在Fedora 17中的所有代码是一个名为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

编译器返回一串提高内部的错误,太多在这里发表。 本文节选似乎是它的核心。 还有它和“手册” S前后的“从要求”一堆。

/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纯浮子和除去return_internal_reference从包装物的.DEF线<>()参数它工作得很好。 这很奇怪,因为我在做另一个,更复杂的类模板同样的事情,它工作得很好那里。 我一直在谷歌上搜索,现在敲我的头这几乎一整天。 任何人有任何想法究竟发生了什么事?

更新:

我结束了使用“的GetItem”和蟒蛇“setitem”特殊的方法,一拉这个链接 。 链接显示了如何定义与访问功能的静态包装一个漂亮的结构模板,所以你不必惹的界面到原来的C ++类。

Answer 1:

从一个python点的视图, floats是一个不可变型。 因此,蟒蛇不允许改变的价值。

例如,以下在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没有重新绑定x ,然后无意义的语句,如6 = 5是可能的。

编译错误是一个静态的检查,限制return_internal_reference只与类或工会的工作,因为这些将是Python的范围内可变类型。 我想,其工作方式“更复杂的类模板”是返回到用户类型的引用。



Answer 2:

简短的回答是可能是你不想要的内部参考返回一个浮点数。 在Python中,数字是不变的,所以只返回一个副本是安全的,并没有牺牲功能或速度。

如果你想返回更复杂的东西(如列表或引用另一个包装类),你可以,但它仍然是几乎总是没有你想要的东西; 一个对象的对其他的依赖性引入脆弱性。 如果你希望能够修改对象的内部状态,你可能使用过的getter和setter,以及进出复制数据更好。



文章来源: intermittent error returning an internal reference with boost.python