最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - For-Iterable wrapper around read-once generator - Stack Overflow

programmeradmin1浏览0评论

Code Link:

I'd like to create a wrapper around a generator to be used in a for-loop:

#include <functional>
#include <iostream>
#include <optional>

// some move-only generator, e.g. it could read some read-once input stream
class Generator {
   public:
    Generator() {}
    Generator(const Generator&) = delete;
    Generator(Generator&&) = default;

    bool hasMore() { return _value < 5; }
    void next() { _value++; }
    int value() const { return _value; }

   private:
    int _value = 0;
};

// wrapper around Generator to make it usable in a for loop
class Iterable {
   public:
    Iterable(Generator gen) : _gen(std::move(gen)) {}

    class EndIterator {};

    class Iterator {
       public:
        Iterator(const Iterator& other) = delete;

        Iterator(Generator gen) : _gen(std::move(gen)) {}

        bool operator!=(EndIterator other) { return _gen.hasMore(); }

        Iterator& operator++() {
            _gen.next();
            return *this;
        }

        int operator*() const { return _gen.value(); }

       private:
        bool _done = false;
        int _next;
        Generator _gen;
    };

    Iterator begin() && { return Iterator(std::move(_gen)); }

    EndIterator end() { return {}; }

   private:
    Generator _gen;
};

int main() {
    Iterable iterable{Generator{}};
    for (auto i : iterable) {
        std::cout << i << std::endl;
    }
    return 0;
}

I made Iterator::begin() to operator on an rvalue this because it moves the generator into the Iterator. However, I get the following error message:

<source>: In function 'int main()':
<source>:55:19: error: passing 'Iterable' as 'this' argument discards qualifiers [-fpermissive]
   55 |     for (auto i : iterable) {
      |                   ^~~~~~~~
<source>:45:14: note:   in call to 'Iterable::Iterator Iterable::begin() &&'
   45 |     Iterator begin() && { return Iterator(std::move(_gen)); }
      |              ^~~~~
Compiler returned: 1

Removing && from Iterator::begin works, but feels semantically wrong. Is there a better option to achieve what I am trying to do and still use it in a for loop?

发布评论

评论列表(0)

  1. 暂无评论