2016-05-09 14 views
5

Ho creato un ring buffer e voglio importare quella classe in Python usando boost. Quando cerco di ottenere questo errore.boost python con template class

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. 

Ecco il mio codice:

#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) 
    ; 
} 

risposta

3

Un modello non è una classe. È necessario creare un'istanza del modello (ad esempio Ring<int> anziché Ring).

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

Inoltre, la parte template <class T> nel codice originale:

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

è un errore di sintassi. Suggerisce che ti aspetti di essere in grado di associare il modello in un modo generico, il che purtroppo non è possibile. Il motivo è che i template sono istanziati in fase di compilazione, cioè il compilatore deve conoscere i tipi esatti con cui il template verrà usato. Se stai interagendo con Python, non puoi saperlo in anticipo, perché sarà deciso in fase di runtime.

Sotto il cofano, Boost.Python genera funzioni di wrapper che prendono il numero PyObject da python e le convertono in valori fortemente tipizzati per i parametri (e i valori di ritorno tornano a PyObject s). Può farlo solo perché conosce i tipi per convertire i valori dinamici da/verso.

Il meglio che puoi fare è creare la classe che non è generica ma che invece funziona con python objects.

MODIFICA: In risposta al tuo commento ("errore: 'init' non è stato dichiarato in questo ambito"), penso che il problema sia che stai includendo solo un'intestazione Boost.Python. O #include <boost/python.hpp> o includi tutte le altre parti di cui hai bisogno (una è init.hpp).

+0

primo anche non funziona, mi dà errore "errore: 'init' non è stato dichiarato in questo ambito". –

+0

@NibinJose Ho aggiornato la mia risposta. –

+0

Sì, ho controllato con la rimozione di "using namespace boost :: python". Ma continua a ricevere errori. –