使用template类提升python

boost python with template class

本文关键字:python template 使用      更新时间:2023-10-16

我创建了一个环形缓冲区,并希望使用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)
    ;
}

模板不是类。您需要实例化您的模板(即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中获取PyObjects,并将它们转换为参数的强类型值(以及返回到PyObjects的值)。它之所以能够做到这一点,是因为它知道将动态值转换为/从中转换的类型。

你能做的最好的事情就是创建一个不是泛型的类,而是用python对象操作。

EDIT:作为对您评论的回应("错误:未在此范围内声明'init'"),我认为问题在于您只包含了一个Boost.Python头。#include <boost/python.hpp>或包含您需要的所有其他部分(其中一个是init.hpp)。