2016-05-09 27 views
5

stworzyłem bufor pierścieniowy i chcę zaimportować klasę Pythonie przy użyciu impuls. Kiedy próbuję to uzyskać błąd.doładowania pyton z klasą szablonu

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. 

Oto mój kod:

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

Odpowiedz

3

Szablon nie jest klasą. Musisz utworzyć instancję szablonu (np. Ring<int> zamiast Ring).

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

Również template <class T> część w oryginalnym kodzie:

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

jest błąd składni. Sugeruje to, że można się spodziewać powiązania z szablonem w sposób ogólny, co niestety nie jest możliwe. Powodem jest to, że szablony są tworzone w czasie kompilacji, tzn. Kompilator musi znać dokładne typy, z których będzie używany szablon. Jeśli współpracujesz z pythonem, nie możesz tego wiedzieć z góry, ponieważ zostanie to ustalone w czasie wykonywania.

Pod maską, Boost.Python generuje funkcje owijające, które pobierają PyObject s z Pythona i konwertują je na mocno wpisane wartości dla twoich parametrów (i zwracane wartości z powrotem do PyObject s). Może to zrobić tylko dlatego, że zna typy do konwersji wartości dynamicznych do/z.

Najlepiej można zrobić jest utworzenie klasy, która nie jest nazwą rodzajową lecz działa z python objects.

EDYCJA: W odpowiedzi na twój komentarz ("błąd:" init "nie został zadeklarowany w tym zakresie"), myślę, że problem polega na tym, że zawierasz tylko jeden nagłówek Boost.Python. Albo #include <boost/python.hpp> lub dołącz wszystkie pozostałe części, których potrzebujesz (jeden to init.hpp).

+0

pierwsza też nie działa, jej daje mi o błędzie „Błąd:«init»nie został zadeklarowany w tym zakresie”. –

+0

@NibinJose Zaktualizowałem swoją odpowiedź. –

+0

Tak, sprawdziłem, usuwając to "używając przestrzeni nazw :: python". Ale wciąż dostaję błąd. –