I'm trying to create a function that takes an underlying container, and returns a boost::iterator_range based on a custom iterator that does some processing on the elements.
E.g.
// The range class, templated on the underlying iterator type
template<class Iter> using CustomRange = boost::iterator_range<CustomIterator<Iter>>;
using std::begin;
template <class Container>
auto make_custom_range(Container& c) -> CustomRange<decltype(begin(c))> {
using std::end;
return make_custom_range_from_iterators(begin(c),end(c));
}
The code works (given suitable definitions for CustomIterator and make_custom_range_from_iterators).
My concern is the using std::begin
declaration, which I think will cause std::begin to be imported into the entire namespace where my function is declared. I prefer not to use std::begin explicitly in the decltype so that ADL can work (as in this question: Relying on ADL for std::begin() and std::end()?).
I think in C++14, I could just use an auto return type here. Is there a C++11 solution? Is there a way to let the return type see the using declaration without exposing it to the entire namespace?
Put the using declaration in a separate namespace:
namespace adl_helper
{
using std::begin;
template <typename T>
auto adl_begin(T&& t) -> decltype(begin(std::forward<T>(t)));
}
template <class Container>
auto make_custom_range(Container& c)
-> CustomRange<decltype(adl_helper::adl_begin(c))>
// ~~~~~~~~~~~~~~~~~~~~^
{
using std::begin;
using std::end;
return make_custom_range_from_iterators(begin(c),end(c));
}