template c++ c++11 template-specialization

c++ - template - ¿Está bien inyectar una especialización en el espacio de nombres estándar?



template partial specialization (2)

En este artículo sobre la definición de sus propias extensiones para ::std::error_code el autor recomienda este código:

namespace std { template <> struct is_error_code_enum<http_error> : public true_type {}; }

para permitir conversiones de sus propias constantes de error al tipo de error del sistema.

¿Es esto razonable? Siempre me pone nervioso poner cosas en el std nombres std . ¿Hay una mejor manera de lograr el objetivo? Si todo esto falla, ¿hay una parte del estándar que diga que siempre está bien hacerlo?


Esto no está bien, es esencial en algunos casos. Lo que no debe hacer es definir funciones / clases / plantillas completamente nuevas dentro de std.

std::swap en particular es una cosa común y simple de especializarse. Algunas clases deben hacer esto para permitir intercambios eficientes, básicamente intercambiar referencias privadas para intercambiar elementos internos en lugar de usar la implementación predeterminada de asignaciones temporales.

EDITAR

El comentario de ildjarn menciona ADL - Argument Dependent name Lookup . La página de Wikipedia menciona específicamente std::swap en las secciones "Interfaces" y "Crítica".

La sección 13.5.2 de Stroustrup (Edición especial) incluye un ejemplo de especialización de std::swap . Citando de eso ...

Estas especializaciones de less() y swap() se utilizan en la biblioteca estándar (16.3.9, 20.3.16). Además, son ejemplos de técnicas ampliamente aplicables.

Siempre he leído que eso indica que la especialización de std::swap era lo correcto, y nunca me preocupé lo suficiente de ADL para cuestionarlo, pero es posible que haya una brecha entre "utilizado en la biblioteca estándar" y "Técnicas ampliamente aplicables": esta técnica no debe utilizarse para especializar std::swap para manejar tipos que no están en la std .

También es posible que haya un problema de estilo que no se había resuelto cuando se publicó la edición especial. AFAIK, Stroustrup ha agregado algunos apéndices adicionales y ha aplicado algunas erratas, pero por lo demás no ha revisado sustancialmente el contenido.

Según la página de Wikipedia, existe un problema potencial con la combinación de la adición de especializaciones y ADL: a veces puede obtener ambigüedad para evitar cualquier búsqueda. Esto solo ocurre si se mezclan las dos técnicas, y de todos modos ADL es conocido por conducir a problemas semánticos. Pero ese argumento solo lleva a "no usar ADL en absoluto", pero ADL existe por una razón.

Bueno, sí, ADL existe por una razón, de modo que las funciones y operadores que no son miembros que trabajan con una hora son visibles junto con el tipo. Pero std::swap no está asociado con un tipo en particular, es genérico, con solo especializaciones particulares asociadas con tipos en particular. Si desea que std::swap sea ​​visible, desea el std nombres std . La ADL no es necesaria para hacer que funcione y, como señala la página de Wikipedia, hay críticas de la ADL.

Lo que esto significa es, básicamente, que no sé. Tengo mis racionalizaciones. No necesariamente están de acuerdo con reglas de estilo más extendidas. Sin duda, este comentario demuestra que no es esencial que se especialice en std::swap ; puede proporcionar su propio swap separado y confiar en ADL en su lugar. Tal vez eso es lo preferido.

Probablemente regresaré y editaré nuevamente después de verificar.


Sí, las especializaciones (para los tipos definidos por el usuario) de los tipos estándar existentes son lo único que puede colocar en el std nombres std , siempre que la especialización cumpla con los requisitos de la plantilla original.

Ver 17.6.4.2.1 en el borrador de C ++ 0x.

Los nuevos tipos, sobrecargas de funciones y cualquier otra cosa, por supuesto, están prohibidos. Pero las especializaciones de plantillas existentes están permitidas.