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 indicatefalseonce 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