C++0x's ranged-for loop has a special exception to handle arrays (FDIS §6.5.4), and there are two functions, std::begin and end, which are overloaded to handle arrays or to select begin/end methods. This leads me to believe a function accepting a generic sequence could be written to match a ranged-for loop's behavior:
template<class C>
void f(C &c) {
using std::begin;
using std::end;
do_something_with(begin(c), end(c));
}
If there's a "more specific" begin/end in the namespace of C, it will be selected through ADL, otherwise the code "defaults" to std::begin/end.
However, there is a reason ranged-for has that special exception. If passing an array of a type in a namespace with a semantically-different begin/end which takes a pointer, the array forms of std::begin/end aren't selected:
namespace ns {
struct A {};
void begin(A*); // Does something completely different from std::begin.
}
void f_A() { // Imagine above f() called with an array of ns::A objects.
ns::A c[42];
using std::begin;
begin(c); // Selects ns::begin, not array form of std::begin!
}
To to avoid this, is there a better solution than writing my own begin/end wrappers (which use ADL internally) and calling them explicitly instead of either std::begin or an ADLized begin?
namespace my {
template<class T>
auto begin(T &c) // Also overload on T const &c, as std::begin does.
-> decltype(...) // See below.
{
using std::begin;
return begin(c);
}
template<class T, int N>
T* begin(T (&c)[N]) {
return c;
}
}
// my::end omitted, but it is analogous to my::begin.
template<class C>
void f(C &c) {
do_something_with(my::begin(c), my::end(c));
}
However, as shown by the ellipsis above, I don't even know how to write my::begin! How can I, for that decltype, select the type that will be selected through a local using-declaration and ADL?