c++ - std::iterator::reference 必须是引用吗?

标签 c++ reference iterator

我已经根据这里的答案实现了一个自定义迭代器:
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/

    相关文章:

    c++ - vector 调整大小 - 可移植检测方式

    c++ - 简单情况下的模板缓冲区行为(GL_ALWAYS、GL_LEQUAL)

    c++ - 类不被认可?

    c# - 有趣的 "params of ref"功能,有什么解决方法吗?

    c++ - 如何为 GraphicsItem 创建自定义属性并在 QPropertyAnimation 中使用它

    c++ - 在 C++ 的单个语句中通过非常量引用使用临时对象

    c++ - 为什么 "auto const&"不是只读的?

    c++ - 如何定义从自定义迭代器到自定义 const_iterator 的隐式转换

    c++ - 如何推导 std::advance 迭代器类型?

    C++ 模板和 STL vector 问题