2008-11-26 19 views
14

Es aceptable agregar tipos al espacio de nombre std. Por ejemplo, quiero una cadena amigable con TCHAR, ¿es aceptable lo siguiente?Agregar tipos al espacio de nombres estándar

#include <string> 

namespace std 
{ 
    typedef basic_string<TCHAR> tstring; 
} 

¿O debería usar mi propio espacio de nombres?

Respuesta

17

No ... parte del objetivo de un espacio de nombres es evitar colisiones de nombres en la actualización.

Si agrega elementos al espacio de nombres estándar, entonces su código podría romperse con el próximo lanzamiento de la biblioteca si deciden agregar algo con el mismo nombre.

+2

También viola el estándar, afaik. El espacio de nombre estándar es sagrado. (Aparte de las especializaciones de las funciones std existentes) :) – jalf

3

Debe usar su propio espacio de nombres ya que agregar código a la biblioteca estándar solo confundirá a los usuarios que buscarán en línea la información sobre esa adición.

Todo lo que está en std debe ser solo la biblioteca estándar y nada más.

+0

No estoy seguro de que confunda a los usuarios; de hecho, pueden esperar que un std :: basic_string sea en std. Tough call, creo. – Rob

+0

No, Klaim tiene razón. No debe agregar nada al espacio de nombres estándar. Los usuarios pueden * esperar que * basic_string sea en std, pero NO es parte de la biblioteca std y no encontrarán nada en la documentación publicada para una implementación std determinada. La forma correcta es usar tu propio ns. –

+0

Tuve que mirar esto. 'basic_string' en realidad se define como parte del espacio de nombres' std' en la página 384 de ISO/IEC 14882: 1998. – Zhro

2

Oficialmente, el estándar dice que es un "comportamiento indefinido" y pueden ocurrir todo tipo de cosas desagradables.

En la práctica, funcionará bien, pero aún no deberías hacerlo. ¿Qué te compra, aparte de confundir a la gente de que algo es proporcionado por el compilador?

15

Solo se permiten especializaciones. Por ejemplo, puedes especializarte en std::numeric_limits para tu tipo. Y esto, por supuesto, debe suceder en el espacio de nombres std::. Pero su typedef no es una especialización, por lo que está causando un comportamiento indefinido.

+0

De acuerdo con [esta respuesta] (http://stackoverflow.com/a/2684544/1468366), las implementaciones 'swap' ya no deberían entrar en' std', ya que los algoritmos que usan 'swap' deben confiar en la búsqueda dependiente del argumento. – MvG

+0

@MvG esa respuesta es correcta. Mi ejemplo no es y no era bueno. Lo reemplazaré –

+0

¿Por qué 'numeric_limits' es diferente de' swap' en este aspecto? –

1

Estoy totalmente de acuerdo con otras respuestas que dicen que debe poner sus tipos en su propio espacio de nombres para evitar colisiones de nombres desafortunados.

Sin embargo, quería precisar que a veces, puede (y debería) agregar cosas en el espacio de nombres estándar. Este es el caso de las especializaciones de plantilla del método std :: swap, por ejemplo, que se utilizan para proporcionar una manera uniforme de intercambiar objetos. Para obtener más información sobre este asunto, puede leer sobre non-throwing swap idiom.

13

[C++11: 17.6.4.2.1/1]: El comportamiento de un programa en C++ es indefinido si se añade declaraciones o las definiciones de espacio de nombres std o para 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.

2

Esta es una pregunta interesante porque es completamente subjetiva para el proyecto y los estándares de codificación aceptados por los ingenieros.

Para un programador único, ¿por qué no ... solo tenga cuidado.

Para los equipos, crea un estándar ...

Para un proyecto multiplataforma, infierno sí.

De lo contrario, nawdawg.

Cuestiones relacionadas