使用模板 class 提升 python
boost python with template class
我创建了一个环形缓冲区,我想使用 boost 将 class 导入到 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)
;
}
模板不是 class。您需要实例化您的模板(即 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)
;
是语法错误。它表明您希望能够以通用方式绑定到模板,不幸的是,这是不可能的。原因是模板在 compile-time 处实例化,即编译器需要知道模板将要使用的确切类型。如果你正在与 python 交互,你无法提前知道,因为它是在运行时决定的。
在幕后,Boost.Python 生成包装函数,从 python 获取 PyObject
s 并将它们转换为参数的强类型值(以及 return值回到 PyObject
s)。它只能这样做,因为它知道转换动态值的类型 to/from.
您能做的最好的事情就是创建非通用但与 python objects 一起运行的 class。
编辑:针对您的评论 ("error: ‘init’ was not declared in this scope"),我认为问题在于您只包括了一个 Boost.Python header。 #include <boost/python.hpp>
或包括您需要的所有其他部分(一个是 init.hpp)。
我创建了一个环形缓冲区,我想使用 boost 将 class 导入到 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)
;
}
模板不是 class。您需要实例化您的模板(即 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)
;
是语法错误。它表明您希望能够以通用方式绑定到模板,不幸的是,这是不可能的。原因是模板在 compile-time 处实例化,即编译器需要知道模板将要使用的确切类型。如果你正在与 python 交互,你无法提前知道,因为它是在运行时决定的。
在幕后,Boost.Python 生成包装函数,从 python 获取 PyObject
s 并将它们转换为参数的强类型值(以及 return值回到 PyObject
s)。它只能这样做,因为它知道转换动态值的类型 to/from.
您能做的最好的事情就是创建非通用但与 python objects 一起运行的 class。
编辑:针对您的评论 ("error: ‘init’ was not declared in this scope"),我认为问题在于您只包括了一个 Boost.Python header。 #include <boost/python.hpp>
或包括您需要的所有其他部分(一个是 init.hpp)。