コンテナのようなオブジェクト(具体的には、PythonのC APIからタプル)へのレガシーC APIがあります。これは素敵なC++ 14 API 、私はイテレータを使用することができます。これを実装するにはどうすればいいですか?C++で従来のC APIをラップしてイテレータをサポートする
ここにいくつかの詳細があります。私たちは、変更することはできません、次の既存のC APIを持っています。
Py_ssize_t PyTuple_GET_SIZE(PyObject *p);
PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos);
void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o)
私たちは、あなたがタプルの要素の読み取り/書き込みイテレータへのアクセスを取得することを可能にするクラスを作成します。
前方読み取り専用イテレータはあまりにも定義するのが難しくありません。ここに私が持っているものがあります:
class PyTuple {
private:
PyObject* tuple;
public:
PyTuple(PyObject* tuple) : tuple(tuple) {}
class iterator {
// iterator traits
PyObject* tuple;
Py_ssize_t index;
public:
iterator(PyObject *tuple, Py_ssize_t index) : tuple(tuple), index(index) {}
iterator& operator++() { index++; return *this; }
iterator operator++(int) { auto r = *this; ++(*this); return r; }
bool operator==(iterator other) const { return tuple == other.tuple && index == other.index; }
bool operator!=(iterator other) const { return !(*this == other); }
PyObject* operator*() { return PyTuple_GET_ITEM(tuple, index); }
// iterator traits
using difference_type = Py_ssize_t;
using value_type = PyObject*;
using pointer = PyObject**;
using reference = PyObject*&;
using iterator_category = std::forward_iterator_tag;
};
iterator begin() {
return iterator(tuple, 0);
}
iterator end() {
return iterator(tuple, PyTuple_GET_SIZE(tuple));
}
}
しかし、私はどのように書き込みをサポートするかについてはあまりよく分かりません。どういうわけか*it = pyobj_ptr
を作っておかなければなりません。従来は、タイプをPyObject*& operator*()
に変更することで(これは左辺値を与えるようになりましたが)、タプル「書き込み」がPyTuple_SET_ITEM
を通過する必要があるため、これを行うことはできません。私はこのケースを解決するのにoperator=
を使うことができると聞いたことがありますが、普遍的なリファレンス(Why no emplacement iterators in C++11 or C++14?)またはプロキシクラス(What is Proxy Class in C++)を使うべきかどうかはわかりません。
例:
は基本的に、あなたはあなたのような何かを与えることを
operator*()
をしたいhttps://stackoverflow.com/a/25938871/315052あなたはのためのベースとしてのstd ::イテレータを使用することを検討すべきである – jxhあなたイテレータ。 –
std :: iteratorはC++で推奨されていません17 https://stackoverflow.com/questions/37031805/preparation-for-stditerator-being-deprecatedこれ以上使用しないと思います! –