У меня есть существующий код, содержащий несколько фасадных_итераторов, и я хотел бы связать их с (C) Python. Схематически моя идея заключается в том, чтобы Python:
- Инициализировать итератор
- Вызовите последовательно dereference () и increment ()
Несколько кодов примеры, которые я видел, показывают только std :: for_each и std :: copy, как здесь, из официального do c https://www.boost.org/doc/libs/1_65_0/libs/iterator/example/node_iterator2.cpp. Но я не хочу перебирать все сразу.
Я попытался включить функции increment () и dereference () publi c, а затем вызвать их напрямую: это работает. Я думаю, что это должно быть достигнуто с помощью boost :: iterator_core_access, но я не могу найти, как. Вот полный код:
// File test.h
#include <iostream>
#include <boost/iterator/iterator_facade.hpp>
struct node_base {
node_base() : m_next(0) {}
virtual ~node_base() { delete m_next; }
node_base* next() const { return m_next; }
virtual void print(std::ostream& s) const = 0;
virtual void double_me() = 0;
void append(node_base* p) {
if (m_next) m_next->append(p);
else m_next = p;
}
private:
node_base* m_next;
};
template <class T>
struct node : node_base {
node(T x) : m_value(x) {}
void print(std::ostream& s) const { s << this->m_value; }
void double_me() { m_value += m_value; }
private:
T m_value;
};
inline std::ostream& operator<<(std::ostream& s, node_base const& n) {
n.print(s);
return s;
}
template <class Value>
class node_iter : public boost::iterator_facade<
node_iter<Value>
, Value
, boost::forward_traversal_tag> {
public:
node_iter() : m_node(0) {}
explicit node_iter(Value* p) : m_node(p) {}
template <class OtherValue>
node_iter(node_iter<OtherValue> const& other) : m_node(other.m_node) {}
//private: //private should start here
friend class boost::iterator_core_access;
template <class> friend class node_iter;
template <class OtherValue>
bool equal(node_iter<OtherValue> const& other) const {
return this->m_node == other.m_node;
}
void increment() { m_node = m_node->next(); }
Value& dereference() const { return *m_node; }
private: //if it's moved here, the example works
Value* m_node;
};
typedef node_iter<node_base> node_iterator;
typedef node_iter<node_base const> node_const_iterator;
// File test.cpp
#include "test.h"
#include <iostream>
#include <memory>
int main() {
std::unique_ptr<node<int> > nodes(new node<int>(42));
nodes->append(new node<int>(13));
auto nit = new node_iterator(nodes.get());
std::cout << nit->dereference() << std::endl;
nit->increment();
std::cout << nit->dereference() << std::endl;
return 0;
}
// How to do the same with private increment() and dereference()?
РЕДАКТИРОВАТЬ: я попытался заменить три последние строки в main () на
std::cout << boost::iterator_core_access::dereference(*nit) << std::endl;
boost::iterator_core_access::increment(*nit);
std::cout << boost::iterator_core_access::dereference(*nit) << std::endl;
Но я получаю сообщение об ошибке, сообщающее, что dereference () и increment () являются частными. Однако, когда я смотрю в исходном коде (boost / iterator / iterator_facade.hpp), кажется, что функции принадлежат к блоку publi c. Так что я в замешательстве.