我有一個遺留的C API給一個類似容器的對象(特別是元組的Python 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*()
(以便它給出一個左值)來完成,但我不能這樣做,因爲元組「write」需要經過PyTuple_SET_ITEM
。我聽說您可以使用operator=
來解決這種情況,但我不確定我是否應該使用通用引用(Why no emplacement iterators in C++11 or C++14?)或代理類(What is Proxy Class in C++),並且我不確定代碼的準確外觀。
例:https://stackoverflow.com/a/25938871/315052 – jxh
您應該考慮使用std ::迭代器爲基礎的迭代器。 –
std :: iterator已被棄用,因爲C++ 17 https://stackoverflow.com/questions/37031805/preparation-for-stditerator-being-deprecated所以我認爲我們不應該再使用它了! –