我已经根据这里的答案实现了一个自定义迭代器:
https://stackoverflow.com/a/31886483/1973454
但是,而不是 Type* _ptr
成员,我的代码最终检索存储在某个单一位置的值,就好像它使用以下函数一样:
// my iterator class gets its values from this function
float globalFloat{ 0 };
float* retrieveFloat (int idx)
{
globalFloat = (float)idx;
return &globalFloat;
}
这意味着为了同时使用两个迭代器(即使用 upper_bound 进行搜索),我必须在允许访问之前在本地缓存浮点数:
class Iterator : public std::iterator<std::random_access_iterator_tag, float, int>
{
public:
Iterator () = default;
Iterator (int idx) : _index (idx) {}
Iterator& operator++ () noexcept { ++_index; return *this; }
Iterator& operator-- () noexcept { --_index; return *this; }
/// ... rest of iterator declaration
const float& operator* () const { _data = *retrieveFloat (_index); return _data; }
const float* operator-> () const { _data = *retrieveFloat (_index); return &this->_data; }
const float& operator[] (int offset) const { _data = *retrieveFloat (_index + offset); return _data; }
private:
int _index{ 0 };
mutable float _data{ 0 };
};
我担心的是最后一个操作符[]。根据 cppreference:
https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
[] 运算符必须返回引用类型。但是,如果我要编写以下代码:
int main (int argc, char ** argv)
{
Iterator it;
if (it[0] == it[1])
return 0;
return 1;
}
然后我返回 0,因为每个 [] 调用都会修改 _data。
如果我更改子类化 std::iterator 的方式并使用 float 作为我的“引用”类型:
class Iterator : public std::iterator<std::random_access_iterator_tag, float, int, float*, float>
{
public:
/// ... rest of iterator declaration (constructors / operators)
const float operator* () const { _data = *retrieveFloat (_index); return _data; }
const float* operator-> () const { _data = *retrieveFloat (_index); return &this->_data; }
const float operator[] (int offset) const { _data = *retrieveFloat (_index + offset); return _data; }
};
然后一切正常……但不知何故感觉很脏。做这种事合法吗?
我知道如果我的数据类型不是浮点数而是更重的东西,那么就会有性能问题,但为了争论,假设我只使用浮点数或轻量级 POD。我们还假设我不需要修改被迭代的数据。
感谢您提供的任何帮助,如果我问这个问题太久,我很抱歉。如果需要,我可以编辑。
最佳答案
Does std::iterator::reference have to be a reference?
号
std::iterator::reference
不需要是引用类型。只需要与 operator*
返回的类型相同并且需要可转换为 value_type
.然而,为了成为
OuputIterator
, *r = o
必须格式正确,因此 reference
必须是引用类型或具有非左值引用限定赋值运算符的类类型。因此,使用 float
适用于非输出迭代器,但不适用于输出迭代器。
关于c++ - std::iterator::reference 必须是引用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60010701/