template c++ c++11 stl iterator template-specialization

template - alias c++



¿Puedo especializar std:: begin y std:: end para el valor de retorno de equal_range()? (1)

17.6.4.2.1 / 1 El comportamiento de un programa C ++ no está definido si agrega declaraciones o definiciones al espacio de nombres std o a un espacio de nombres dentro del espacio de nombres std menos que se especifique lo contrario. Un programa puede agregar una especialización de plantilla para cualquier plantilla de biblioteca estándar al espacio de nombre std solo si la declaración depende de un tipo definido por el usuario y la especialización cumple con los requisitos de biblioteca estándar para la plantilla original y no está explícitamente prohibida.

Entonces, sí, creo que, técnicamente, su código exhibe un comportamiento indefinido. Quizás puedas escribir una clase simple que tome un par de iteradores en su constructor e implemente los métodos begin() y end() . Entonces puedes escribir algo como

for (const auto& elem: as_range(equal_range(...))) {}

El encabezado <algorithm> proporciona std::equal_range() , así como algunos contenedores que lo tienen como función miembro. Lo que me molesta con esta función es que devuelve un par de iteradores, por lo que es tedioso iterar desde el iterador de inicio hasta el iterador final. Me gustaría poder usar std::begin() y std::end() para poder usar el for-loop basado en el rango de C ++ 11.

Ahora, he escuchado información contradictoria con respecto a la especialización de std::begin() y std::end() - Me han dicho que agregar algo al espacio de nombres std da como resultado un comportamiento indefinido, mientras que también me han dicho que puede proporcionar sus propias especializaciones de std::begin() y std::end() .

Esto es lo que estoy haciendo en este momento:

namespace std { template<typename Iter, typename = typename iterator_traits<Iter>::iterator_category> Iter begin(pair<Iter, Iter> const &p) { return p.first; } template<typename Iter, typename = typename iterator_traits<Iter>::iterator_category> Iter end(pair<Iter, Iter> const &p) { return p.second; } }

Y esto funciona: http://ideone.com/wHVfkh

Pero me pregunto, ¿cuáles son los inconvenientes de hacer esto? ¿Hay una mejor manera de hacer esto?