¿Qué problema resuelve esto?
Ver la respuesta de Dietmar y la respuesta de remyabel .
¿Y esto cambia el funcionamiento de los contenedores estándar?
No, no por defecto.
Las nuevas sobrecargas de plantilla de función miembro de find
etc. le permiten usar un tipo que es comparable con la clave del contenedor, en lugar de usar el tipo de clave en sí. Ver N3465 de Joaquín Mª López Muñoz para la justificación y una propuesta detallada y cuidadosamente escrita para agregar esta característica.
En la reunión de Bristol, el LWG acordó que la función de búsqueda heterogénea era útil y deseable, pero no podíamos estar seguros de que la propuesta de Joaquín fuera segura en todos los casos. La propuesta N3465 habría causado serios problemas para algunos programas (consulte la sección Impacto en el código existente ). Joaquín preparó un borrador de propuesta actualizado con algunas implementaciones alternativas con diferentes compensaciones, lo cual fue muy útil para ayudar al LWG a comprender los pros y los contras, pero todos corrían el riesgo de romper algunos programas de alguna manera, por lo que no hubo consenso para agregar la función. Decidimos que, aunque no sería seguro agregar la función incondicionalmente, sería seguro si estuviera deshabilitada de forma predeterminada y solo "habilitada".
La diferencia clave de la propuesta N3657 (que fue una revisión de última hora por mí y STL basada en N3465 y un borrador inédito posterior de Joaquín) fue agregar el is_transparent
tipo como el protocolo que se puede usar para optar por la nueva funcionalidad.
Si no usa un "functor transparente" (es decir, uno que define un is_transparent
tipo), los contenedores se comportan de la misma manera que siempre lo han hecho, y ese sigue siendo el predeterminado.
Si elige usar std::less<>
(que es nuevo para C ++ 14) u otro tipo de "functor transparente", obtendrá la nueva funcionalidad.
Usar std::less<>
es fácil con las plantillas de alias:
template<typename T, typename Cmp = std::less<>, typename Alloc = std::allocator<T>>
using set = std::set<T, Cmp, Alloc>;
El nombre is_transparent
proviene del N3421 de STL que agregó los "operadores de diamante" a C ++ 14. Un "functor transparente" es uno que acepta cualquier tipo de argumento (que no tiene que ser el mismo) y simplemente reenvía esos argumentos a otro operador. Tal functor resulta ser exactamente lo que desea para la búsqueda heterogénea en contenedores asociativos, por lo que el tipo is_transparent
se agregó a todos los operadores de diamante y se usó como tipo de etiqueta para indicar que la nueva funcionalidad debe habilitarse en contenedores asociativos. Técnicamente, los contenedores no necesitan un "functor transparente", solo uno que admita llamarlo con tipos heterogéneos (por ejemplo, el pointer_comp
tipo en https://stackoverflow.com/a/18940595/981959 no es transparente según la definición de STL,pointer_comp::is_transparent
permite que se utilice para solucionar el problema). Si sólo las operaciones de búsqueda nunca en su std::set<T, C>
con claves de tipo T
o int
entonces C
sólo tiene que haber exigible con argumentos de tipo T
y int
(en cualquier orden), que no tiene por qué ser verdaderamente transparente. Usamos ese nombre en parte porque no pudimos encontrar un nombre mejor (hubiera preferido is_polymorphic
porque tales functores usan polimorfismo estático, pero ya existe un std::is_polymorphic
rasgo de tipo que se refiere al polimorfismo dinámico).