1

I have a function that gets a pair of input iterators:

template<typename I>
void foo(I begin, I end) {...}

I'd like to feed it with sequence generated by function - for example a sequence of random numbers. Is there any standard library mechanism to achieve this without necessity to store the sequence in a collection and then take iterators from collection?

ardabro
  • 1,907
  • 16
  • 31
  • I don't want to narrow the problem. I want a pair of iterators over a sequence not stored in any collection. – ardabro May 09 '20 at 22:28
  • 1
    There's a precedent in the standard library: `istream_iterator`. You can write yours along the same lines, but there's nothing in the standard library to help you do that. – Igor Tandetnik May 09 '20 at 22:32
  • Is this question similar enough to yours to be helpful? https://stackoverflow.com/questions/9059187/equivalent-c-to-python-generator-pattern – Wyck May 09 '20 at 22:55

1 Answers1

0

You will need to build that yourself. Here is an example of how to do it:

template<typename F>
class function_iterator {
    using function = F;
public:
    using value_type = std::invoke_result_t<function>;
    using difference_type = std::ptrdiff_t;
    using reference = value_type const&;
    using pointer = value_type const*;
    using iterator_category = std::input_iterator_tag;

    function_iterator(function f, difference_type pos = 0);

    auto operator*() const -> value_type;
    auto operator++() -> function_iterator&;
    auto operator++(int) -> function_iterator;

private:
    function f_;
    difference_type pos_;

    template<typename T_>
    friend bool operator==(function_iterator<T_> const& lhs, function_iterator<T_> const& rhs);
    template<typename T_>
    friend bool operator!=(function_iterator<T_> const& lhs, function_iterator<T_> const& rhs);
};

template<typename T>
function_iterator<T>::function_iterator(function f, difference_type pos) :
f_(f), pos_(pos) {
}

template<typename F>
auto function_iterator<F>::operator*() const -> value_type {
    return f_();
}
template<typename F>
auto function_iterator<F>::operator++() -> function_iterator& {
    ++pos_;
    return *this;
}
template<typename F>
auto function_iterator<F>::operator++(int) -> function_iterator {
    auto it = *this;
    ++*this;
    return it;
}

template<typename T_>
bool operator==(function_iterator<T_> const& lhs, function_iterator<T_> const& rhs) {
    return lhs.pos_ == rhs.pos_;
}
template<typename T_>
bool operator!=(function_iterator<T_> const& lhs, function_iterator<T_> const& rhs) {
    return !(lhs == rhs);
}

Live

Nelfeal
  • 12,593
  • 1
  • 20
  • 39