如何在C++11中编写一个简单的、类型擦除的可组合迭代器

How to write a simple, type-erased composable iterator in C++11

本文关键字:简单 一个 类型 迭代器 可组合 擦除 C++11      更新时间:2023-10-16

我正在尝试编写一个简单的可组合迭代器,它不公开内部类型(这样我就可以在接口中使用这些迭代器之一,并可以实现不同的操作,如concat、filter…)。它确实很简单,但我目前遇到了一个无法解决的简单编译错误

#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include <functional>
#include <vector>
template <typename T>
struct RangeIteratorData
{
    std::function<T&()> dereference;
    std::function<void()> increment;
};
template <typename T>
class RangeIterator
{
public:
    template <typename I>
    RangeIterator(I& iter)
    {
        auto dereference = [iter]() { return *iter; };
        auto increment = [iter]() -> void { ++iter; }; //here's the error
        m_data.dereference = dereference;
        m_data.increment = increment;
    }
    T& operator*();
    RangeIterator<T>& operator++();
private:
    RangeIteratorData<T> m_data;
};
template <typename T>
RangeIterator<T>& RangeIterator<T>::operator++()
{
    m_data.increment();
    return *this;
}
template <typename T>
T& RangeIterator<T>::operator*()
{
    return m_data.dereference();;
}
TEST_CASE("Wrap existing iterator in range iterator")
{
    std::vector<int> container{ 1,2,3 };
    RangeIterator<int> begin = RangeIterator<int>(container.begin());
    ++begin;
    REQUIRE(*begin == 1);
}

错误消息为:

错误C2678二进制"++":找不到接受类型为"const std::_Vector_editor>>"的左侧操作数的运算符(或者没有可接受的转换)

我使用的是VS2015。代码本身还远远不够完整,但我不明白这个错误消息的含义。我特别不明白const是从哪里来的。

如果有人能给我指正确的位置就好了。

auto increment = [iter]() -> void { ++iter; };

将此行更改为:

auto increment = [iter]() mutable -> void { ++iter; };

如果没有mutable,lambda类型的operator()成员函数就是const,所以它不能修改迭代器。