Boost python level with template class

I created a ring buffer, and I want to import this class into Python using boost. When I try this get an error.

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. 

Here is my code:

 #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) ; } 
+5
source share
1 answer

A template is not a class. You need to create an instance of the template (i.e. Ring<int> instead of Ring ).

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

Also, the template <class T> part in your source code:

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

is a syntax error. This assumes that you expect that you can attach to the template in a general way, which, unfortunately, is not possible. The reason is that templates are created at compile time, i.e. The compiler must know the exact types with which the template will be used. If you interact with python, you cannot know this in advance because it will be determined at runtime.

Under the hood, Boost.Python generates wrapper functions that take PyObject from python and convert them to strongly typed values ​​for your parameters (and the return values ​​return to PyObject s). He can do this only because he knows the types for converting dynamic values ​​to / from.

The best you can do is create a class that is not generic, but works with python objects instead.

EDIT: In response to your comment ("error:" init has not been declared in this area "), I think the problem is that you include only one Boost.Python header. Either #include <boost/python.hpp> , or specify all the other parts that you need (one is init.hpp).

+3
source

All Articles