Boost.Range provides some little gems like boost::adaptors::filtered
and boost::adaptors::transformed
, which can be used to write sophisticated range-based for
loops.
However, in same cases we would like to factor the code that creates that range out of the function in which the iteration takes place; something like:
auto final_range = make_final_range(initial_range);
for (auto&& e: final_range) {...}
Since Boost.Ranges is heavily templetized, the return type of make_final_range
might be difficult to pinpoint precisely.
I recently found a discussion on SO about this issue, with several possible proposals on how to overcome the problem in C+11. Quoting one of the comments:
I think the problem can be solved in an other way as well: Defining a global lambda variable in a
detail
orhidden
namespace, then use thedecltype
for that lambda variable
Hence:
namespace detail {
auto make_final_range = (std::vector<int>& v) {
using boost::adaptors::transformed;
return v | transformed([](int i){return i + 2;});
};
}
auto make_final_range(std::vector<int>& v) -> decltype(detail::make_final_range(v)) {
return detail::make_final_range(v);
}
}
int main() {
std::vector<int> v = {1, 2, 3};
auto final_range = make_final_range(v);
for (auto&& e: v) {...}
}
UPDATE: Here's a second article on the topic