Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何制作C++;使用SWIG从Python中初始化iterable? 我有一个C++类集合管理一个 STD::vector < /Cl> >(类的私有成员)。< /P> < >从C++中,我可以使用 >开始)< /C>和Enter()/迭代器(这只是对代码< vector \ < /代码>的迭代器的Type DEFS)进行迭代:_Python_C++_Iterator_Swig - Fatal编程技术网

如何制作C++;使用SWIG从Python中初始化iterable? 我有一个C++类集合管理一个 STD::vector < /Cl> >(类的私有成员)。< /P> < >从C++中,我可以使用 >开始)< /C>和Enter()/迭代器(这只是对代码< vector \ < /代码>的迭代器的Type DEFS)进行迭代:

如何制作C++;使用SWIG从Python中初始化iterable? 我有一个C++类集合管理一个 STD::vector < /Cl> >(类的私有成员)。< /P> < >从C++中,我可以使用 >开始)< /C>和Enter()/迭代器(这只是对代码< vector \ < /代码>的迭代器的Type DEFS)进行迭代:,python,c++,iterator,swig,Python,C++,Iterator,Swig,但这导致: TypeError:“集合”对象不可编辑 我无法配置SWIG,使其为Python集合类生成(我认为这是它唯一需要的东西)。我该怎么做 这是我的代码: 例h: 例一: 灵感来源于最后一个示例:。我提出了一种稍微不同的方法,它不使用变量来检查StopIterator异常状态 此外,它只使用Collection的begin()endend()迭代器,无需公开std::vector本身 例一: 我唯一不知道的是如何创建一个模板版的Iterator,这样我就可以传递任何Iterator,而不必

但这导致:

TypeError:“集合”对象不可编辑

我无法配置SWIG,使其为Python
集合
类生成
(我认为这是它唯一需要的东西)。我该怎么做

这是我的代码:

例h:

例一:


灵感来源于最后一个示例:。我提出了一种稍微不同的方法,它不使用变量来检查StopIterator异常状态

此外,它只使用
Collection
begin()
end
end()
迭代器,无需公开
std::vector
本身

例一:


我唯一不知道的是如何创建一个模板版的
Iterator
,这样我就可以传递任何
Iterator
,而不必为每个模板实例重新定义
next()
。欢迎提供解决方案;)

这个答案怎么样@Shawn这是一个很有帮助的评论,事实上我可以像那样实现它,但是如果不将我的
std::vector
公开,我看不到解决方法(我也不想在(size\t I)
上实现
)。如何在向量为私有的情况下实现
\uuu getitem\uuu
?我还希望返回对元素的引用,但是如果索引超出范围,我应该返回什么呢?您只需使用与
std::vector
Collection
关联的代理类即可。在您的情况下,无法自动生成iterable接口。查看SWIG分布中的
vector.i
Collection col;
for (Collection::const_iterator itr = col.begin(); itr != col.end(); itr++)
{
  std::cout << itr->get() << std::endl;
}
import example
el = example.Element()
el.set(5)
col = example.Collection()
col.add(el)
for e in col:
    print e.get()
#include <vector>

class Element
{
public:
  Element();
  ~Element();

  int get() const;
  void set(const int var);

private:
  int variable_;
};

class Collection
{
public:
  Collection();
  ~Collection();

  void add(const Element& element);

  typedef std::vector<Element> tElements;

  // iterators
  typedef tElements::iterator iterator;
  typedef tElements::const_iterator const_iterator;
  iterator begin();
  const_iterator begin() const;
  iterator end();
  const_iterator end() const;

private:
  tElements          elements_;
};
#include "example.h"

Element::Element() {}

Element::~Element() {}

int Element::get() const
{
  return variable_;
}

void Element::set(const int var)
{
  variable_ = var;
}

Collection::Collection() : elements_() {}

Collection::~Collection() {}

void Collection::add(const Element& element)
{
  elements_.push_back(element);
}

Collection::iterator Collection::begin()
{
  return elements_.begin();
}

Collection::const_iterator Collection::begin() const
{
  return elements_.begin();
}

Collection::iterator Collection::end()
{
  return elements_.end();
}

Collection::const_iterator Collection::end() const
{
  return elements_.end();
}
%module example
%{
#include "example.h"
%}

// I've tried to add this, but that generates a whole
// other class, that is not what I want.
// %include "std_vector.i"
// %template(ElementVector) std::vector<Element>;

// I've also tried to %extend the class (which I think is what I want,
// but I cannot figure out with what to extend it with)

// Include the header file with above prototypes
%include "example.h"
swig -python -c++ -o example_wrap.cpp example.i
g++ -fPIC -c example.cpp example_wrap.cpp -I/usr/include/python2.6
g++ -shared example.o example_wrap.o -o _example.so
%module example
%{
#include "example.h"
%}

%inline %{
class StopIterator {};
class Iterator {
  public:
    Iterator(Collection::iterator _cur, Collection::iterator _end) : cur(_cur), end(_end) {}
    Iterator* __iter__()
    {
      return this;
    }
    Collection::iterator cur;
    Collection::iterator end;
  };
%}

%include "example.h"

%include "exception.i"
%exception Iterator::next {
  try
  {
    $action // calls %extend function next() below
  }
  catch (StopIterator)
  {
    PyErr_SetString(PyExc_StopIteration, "End of iterator");
    return NULL;
  }
}

%extend Iterator
{
  Element& next()
  {
    if ($self->cur != $self->end)
    {
      // dereference the iterator and return reference to the object,
      // after that it increments the iterator
      return *$self->cur++;
    }
    throw StopIterator();
  }
}

%extend Collection {
  Iterator __iter__()
  {
    // return a constructed Iterator object
    return Iterator($self->begin(), $self->end());
  }
};