mercredi 4 novembre 2015

C++11 Lambda Generator - How to signal last element or end?

I am looking at the lambda generators from http://ift.tt/1kbZOwg and http://ift.tt/1WBb5lH. I would like to adapt these to a template version and I'm wondering what I should return to signal that the generator has reached its end.

Consider

template<typename T>
std::function<T()> my_template_vector_generator(std::vector<T> &v) {
    int idx = 0;
    return [=,&v]() mutable {
        return v[idx++];
    };
}

The [=,&v] addition is mine and I hope it's correct. For now, it lets me change the vector outside as expected. Please comment on this if you have a bad feeling about it... For reference, this works (REQUIRE is from catch):

std::vector<double> v({1.0, 2.0, 3.0});
auto vec_gen = my_template_vector_generator(v);
REQUIRE( vec_gen() == 1 );
REQUIRE( vec_gen() == 2 );
v[2] = 5.0;
REQUIRE( vec_gen() == 5.0 );

That vector version obviously requires knowledge of v.size() at the call site. I'd like to go without that by returning something that indicates the generator is empty.

Brainstorming, I can think of the following:

  • return pair<T, bool> and indicate false once there are no more values.
  • return iterators to the container values and iterate for (auto it=gen(); it!=gen.end(); it=gen()) {cout << *it << endl;}
  • wrapping the generator in a class and implementing an empty() method. Not entirely sure how that would work, however.

Does either of these versions feel good to you? Do you have another idea? I'd particularly be interested in implications when mapping such a generator or combining them recursively (see this C++14 blog post for inspiration).

Aucun commentaire:

Enregistrer un commentaire