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 or hidden namespace, then use the decltype for that lambda variable


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