用模板类提升python

时间:2016-05-09 09:17:09

标签: c++ boost boost-python

我创建了一个环形缓冲区,我想使用boost将该类导入Python。当我试图得到它的错误。

ring.cpp: In function ‘void init_module_ring()’:
ring.cpp:130:16: error: wrong number of template arguments (1, should be 4)
 class_<Ring>("Ring").Please help me. Thanks in Advance.

这是我的代码:

#include <boost/python/def.hpp>
#include<iostream>
using namespace std;
using namespace boost::python;


template <class T>
class Ring
   {
   public:
   class iterator;
   public:
    unsigned int m_size;
    unsigned int pos;
    T *val;
    Ring():
    m_size(0),pos(0),val(NULL){};
    Ring(int size):m_size(size),pos(0){
        val=new T[m_size];
    };
    Ring(const Ring &other)
        {
        this->m_size = other.m_size;
        this->pos= other.pos;
        this->val = other.val;

        }
    ~Ring()
        {
        delete[] val;
        }
    void insert(T data)
        {
        val[pos]= data;
        pos++;
        if(pos==m_size)
        pos=0;

        }
    void displayall()
    {
       for(int i =0;i<m_size;i++)
       {
       cout<<val[i]<<' ';
       }
    }
    iterator begin()
    {
       return iterator(val);
    }
    iterator end()
    {
       return iterator(val + m_size);
    }
    unsigned int size()
    {
       return m_size;
   }
   void check()
   {
      cout<<val<<' ';
      cout<<val+5;
   }
    };
template<class T>
class Ring<T>::iterator
{
   T *it_value;
   public:
   iterator():it_value(NULL){};
   iterator(T *value)
   {
   it_value = value;
   };
   iterator(const iterator &other)
   {
       this->it_value = other.it_value;
   }
   friend ostream& operator<<(ostream &out,iterator it)
      {
      out<<*it.it_value;
      return out;
      }
   iterator operator++()
      {
      it_value  +=1;
      return (iterator(it_value));
      }
   iterator operator++(const int x)
      {
      it_value = it_value+ x+1;
      return(iterator(it_value));
      }
   bool operator==(const iterator &other) const
       {
       return (*it_value == *(other.it_value));
       };
   bool operator!=(const iterator &other) const
   {
   return (!(*this == other));
   };
   iterator operator*()
      {
      return *this;
      }
   void display()
       {
       cout<<*it_value<<' ';
       }
};

BOOST_PYTHON_MODULE(ring)
{
    class_<Ring>("Ring")
        template <class T>
        .def(init<int>())
        .def("insert", &Ring::insert)
        .def("display_all", &Ring::displayall)
    ;
}

1 个答案:

答案 0 :(得分:4)

模板不是类。您需要实例化您的模板(即Ring<int>而不是Ring)。

class_<Ring<int>>("IntRing", init<int>())
    .def("insert", &Ring<int>::insert)
    .def("display_all", &Ring<int>::displayall)
;

此外,原始代码中的template <class T>部分:

class_<Ring>("Ring")
    template <class T> // error
    .def(init<int>())
    .def("insert", &Ring::insert)
    .def("display_all", &Ring::displayall)
;

是语法错误。它表明您希望能够以通用方式绑定到模板,遗憾的是这是不可能的。原因是模板在编译时被实例化,即编译器需要知道模板将要使用的确切类型。如果你正在与python接口,你不能提前知道,因为它是在运行时决定的。

在引擎盖下,Boost.Python生成包装函数,从python中获取PyObject并将它们转换为参数的强类型值(并将返回值返回到PyObject s)。它只能这样做,因为它知道将动态值转换为/来自的类型。

您可以做的最好的事情是创建非通用的类,而是使用python objects进行操作。

编辑:在回复你的评论时(&#34;错误:'init'未在此范围内声明&#34;),我认为问题是你只包含一个Boost.Python标题。 #include <boost/python.hpp>或包含您需要的所有其他部分(一个是init.hpp)。