El bucle ranurado de C++ 0x tiene una excepción especial para manejar matrices (FDIS §6.5.4), y hay dos funciones, std :: begin y end, que están sobrecargados para manejar matrices o para seleccionar métodos de inicio/finalización. Esto me lleva a pensar en función de aceptar una secuencia genérica podría escribirse para que coincida con un variado-por el comportamiento del bucle:A partir genéricamente, más decltype teniendo en cuenta la declaración de uso local
template<class C>
void f(C &c) {
using std::begin;
using std::end;
do_something_with(begin(c), end(c));
}
Si hay un "más específica" Introducción/fin en el espacio de nombres de C, se seleccionará a través de ADL; de lo contrario, el código "predeterminado" es std :: begin/end.
Sin embargo, hay un motivo variado, ya que tiene esa excepción especial. Si pasar una matriz de un tipo en un espacio de nombres con un comenzar/final semánticamente diferente que toma un puntero, las formas de matriz de std :: comenzar/final no son seleccionados:
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!
}
Para evitar esto, ¿Existe una solución mejor que escribir mis propios envoltorios de inicio/finalización (que usan ADL internamente) y llamarlos explícitamente en lugar de std :: begin o 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));
}
Sin embargo, como se muestra por las elipsis anteriores, ni siquiera sé cómo escribir mi :: comenzar! ¿Cómo puedo, para ese decltype, seleccionar el tipo que se seleccionará a través de una declaración de uso local y ADL?
Tardé unos 30 minutos en pensar y escribir esta pregunta, pero es algo que se ha estado gestando en mi cabeza por un tiempo, y creo que escribirlo me dio una idea para resolver el "decltype considerando el uso local- declaración ", pero no es bonita. Voy a auto-responder si nadie lo menciona alguna vez hoy. –
Creo que hay otro problema: ¿no se consideraría :: :: begin para "return begin (c);" y, si se selecciona, ¿será recursión infinita? –
@Fred: este segundo problema es simple y solo requiere un contenedor de función adicional en un espacio de nombres de "detalles" separado. –