制作可用于初始化向量的迭代器

时间:2018-07-11 17:06:42

标签: c++ iterator

我在为类创建可用于初始化向量的迭代器类型时遇到麻烦。也许可以用一些代码最好地解释一下,这是我的实现示例:

#include <tuple>
#include <cstdint>

struct Foo
{
public:
    Foo(uint8_t i) : i(i) {}
    struct iterator
    {
    public:
        using value_type = std::pair<int, bool>;
        using reference = value_type;
        using pointer = value_type*;
        using iterator_category = std::input_iterator_tag;

        bool operator == (const iterator& other) { return cur == other.cur; }
        bool operator != (const iterator& other) { return !(*this == other); }

        iterator& operator ++ () { if (cur > -1) --cur; return *this; }
        iterator operator ++ (int) { iterator tmp = *this; ++(*this); return tmp; }

        reference operator * () { return std::make_pair<int, bool>(8 - cur, foo->i & (1 << cur)); }
        pointer operator -> () { static value_type v; v = *(*this); return &v; }
    private:
        friend Foo;
        iterator(const Foo* foo, int start) : foo(foo), cur(start) {}
        const Foo* foo;
        int cur;
    };

    iterator begin() const { return iterator(this, 7); }
    iterator end() const { return iterator(this, -1); }

    uint8_t i;
};

课堂活动的逻辑并不重要;这是一个事实,尽管我可以在for循环中使用此迭代器,但是在尝试从中构造向量时出现错误:

#include <iostream>
#include <vector>

// struct Foo...

int main()
{
    Foo foo(73);

    // Works, output as expected
    for (auto elem : foo)
        std::cout << "Position " << elem.first << " is a " << elem.second << '\n';

    // Works, output as expected
    for (auto it = foo.begin(), end = foo.end(); it != end; ++it)
        std::cout << "Position " << it->first << " is a " << it->second << '\n';

    // Error: cannot convert argument 1 from 'PowersOf2::iterator' to 'const unsigned __int64'
    std::vector<std::pair<int, bool>> v(foo.begin(), foo.end());
}

cppreference告诉我std::vector的构造函数使用两个迭代器,如果InputIt满足InputIterator 。 It also tells me对InputIterator的要求是

  1. 满足迭代器
  2. 满足 EqualComparable
  3. i != j*ii->m++i(void)i++*i++有效

所以我不确定出了什么问题。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:1)

根据cccpreference.com,采用迭代器“的std::vector构造函数,如果InputIt满足InputIterator,则仅参与重载解析,以避免与重载(2)产生歧义。

要满足InputIterator,类型必须满足Iterator。反过来,Iterator要求类型提供几种类型别名,其中包括您已省略的difference_type

尝试将公用类型别名using difference_type = std::ptrdiff_t;添加到迭代器类型。

相关问题