c++ - Boost::python 和来自基类虚函数的迭代器

标签 c++ boost-python virtual-functions

所以我正在尝试编写一个基类来处理包装 std::vector 的类,我正在努力定义 __iter__ 函数。我的第一种方法,也是我希望开始工作的方法,是在基类中包含 begin() 和 end() 函数。这样做编译得很好,但是当我在 python 中运行代码时,我得到一个看起来类似于以下内容的错误:

Boost.Python.ArgumentError: Python argument types in

Container.__iter__(Container)

不匹配 C++ 签名:

__iter__(boost::python::back_reference< stl_iter< std::vector< std::shared_ptr< K > > std::allocator< std::shared_ptr< K > > > >&>)

可以使用以下示例扩展进行测试

from test import *

c = Container()

for i in range(10):
    c.append(K(str(i)))

for i in c:
    print i

示例扩展:

#include <memory>
#include <vector>
#include <string>
#include <boost/python.hpp>

template<class T> 
T* get_pointer(std::shared_ptr<T> const& p) { return p.get(); }

template<class T>
class stl_iter {
protected:
    typedef typename T::value_type V;
    typedef typename T::iterator iter;
    virtual T& get_vector()=0;
public:
    virtual ~stl_iter() {}

    virtual void append(V item) {
        get_vector().push_back(item);
    }

    virtual iter begin() {
        return get_vector().begin();
    }

    virtual iter end() {
        return get_vector().end();
    }
};

class K {
    std::string val;
public:
    K(std::string s) : val(s) {}

    std::string get_val() const { return val; }
};
typedef std::shared_ptr<K> pK;
typedef std::vector<pK> vK;

class Container : public stl_iter<vK> {
    vK items;
protected:
    vK& get_vector() { return items; }

public:
    // Works if I uncomment these
    //vK::iterator begin() { return get_vector().begin(); }
    //vK::iterator end() { return get_vector().end(); }


public:
    virtual ~Container() {}
};
typedef std::shared_ptr<Container> pContainer;
typedef std::vector<pContainer> vContainer;

BOOST_PYTHON_MODULE_INIT(test) {
    using namespace boost::python;

    class_<K, pK>("K", init<std::string>())
        .def("__str__", &K::get_val)
        ;

    class_<Container, pContainer>("Container")
        .def("append", &Container::append)
        .def("__iter__", range(&Container::begin, &Container::end))
        ;
}

最佳答案

答案其实很简单:让容器表现得像一个STL容器,然后使用boost的iterator<>()函数而不是 range() .

为此,我必须在 stl_iter 中创建 typedef。 public,并将它们重命名为 value_typeiterator .

这是更新后的 C++ 代码。

#include <memory>
#include <vector>
#include <string>
#include <boost/python.hpp>

template<class T> 
T* get_pointer(std::shared_ptr<T> const& p) { return p.get(); }

template<class T>
class stl_iter {
protected:
    virtual T& get_vector()=0;
public:
    // Next two lines changed, and made public
    typedef typename T::value_type value_type;
    typedef typename T::iterator iterator;

    virtual ~stl_iter() {}

    virtual void append(value_type item) {
        get_vector().push_back(item);
    }

    virtual iterator begin() {
        return get_vector().begin();
    }

    virtual iterator end() {
        return get_vector().end();
    }
};

class K {
    std::string val;
public:
    K(std::string s) : val(s) {}

    std::string get_val() const { return val; }
};
typedef std::shared_ptr<K> pK;
typedef std::vector<pK> vK;

class Container : public stl_iter<vK> {
    vK items;
protected:
    vK& get_vector() { return items; }

public:
    virtual ~Container() {}
};
typedef std::shared_ptr<Container> pContainer;
typedef std::vector<pContainer> vContainer;

BOOST_PYTHON_MODULE_INIT(test) {
    using namespace boost::python;

    class_<K, pK>("K", init<std::string>())
        .def("__str__", &K::get_val)
        ;

    class_<Container, pContainer>("Container")
        .def("append", &Container::append)
        // Use iterator() instead of range()
        .def("__iter__", iterator<Container>())
        ;
}

关于c++ - Boost::python 和来自基类虚函数的迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8207034/

相关文章:

c++ - 通过 std::shared_ptr 使用 Rcpp 和 RcppParallel 的线程安全函数指针

c++ - 专门化模板模板参数的麻烦

c++ - cout 和 printf

c++ - Boost::Python:嵌入和加载 Boost::Python 模块和转换器

c++ - boost python无法访问ios私有(private)项目

c# - 为什么 C# 不支持显式实现的虚拟方法?

c++ - 添加更多代码会使代码无法编译

python - Mac OS X 上的 Boost.Python Hello World

c++ - "pure virtual function call"崩溃从何而来?

c++ - 使用虚拟方法纠正行为