use*_*454 5 c++ iterator reference
我已经根据这里的答案实现了一个自定义迭代器: 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;
}
Run Code Online (Sandbox Code Playgroud)
这意味着为了同时使用两个迭代器(即使用 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 };
};
Run Code Online (Sandbox Code Playgroud)
我担心的是最后一个运算符[]。根据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;
}
Run Code Online (Sandbox Code Playgroud)
然后我返回 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; }
};
Run Code Online (Sandbox Code Playgroud)
然后事情就可以了……但不知怎的,感觉很脏。做这种事合法吗?
我知道,如果我的数据类型不是浮点数,而是需要更繁重的复制,那么就会出现性能问题,但为了论证起见,我们假设我只使用浮点数或轻量级 POD。我们还假设我不需要修改正在迭代的数据。
感谢您提供的任何帮助,如果我问这个问题太长,我很抱歉。如果需要的话我可以编辑。
std::iterator::reference 是否必须是引用?
No.std::iterator::reference不需要是引用类型。它只需要与返回的类型相同operator*并且可以转换为value_type.
但是,为了成为OuputIterator,*r = o必须格式良好,因此reference必须是引用类型或具有非左值引用限定赋值运算符的类类型。因此, usingfloat对于非输出迭代器来说很好,但对于输出迭代器则不好。
| 归档时间: |
|
| 查看次数: |
455 次 |
| 最近记录: |