2009-11-02 18 views
23

Me parece que el uso de espacios de nombres sin anclaje es solo un problema más adelante cuando alguien pone un nuevo espacio de nombres que tiene el mismo nombre que un espacio de nombres de nivel raíz y misteriosamente altera el significado de una gran cantidad de programas. Entonces, ¿por qué la gente siempre dice std:: en lugar de ::std::? ¿De verdad quieren decir "Quiero usar lo que sea std útil, no la raíz"?¿Por qué todos usan declaraciones de espacio de nombres sin anclaje (es decir, std :: not :: std: :)?

Aquí es un ejemplo de lo que quiero decir:

En Fred/foo.h:

#include <string> 

namespace fred { 

class Foo { 
public: 
    void aPublicMember(const std::string &s); 
}; 

} // end namespace fred 

En Fred/Bar.h:

namespace fred { 
namespace std { // A standard fred component 

class string { // Something rather unlike the ::std::string 
    // ... 
}; 

} // namespace std 

class Bar { 
public: 
    void aPublicMember(std::string &s); 
}; 

} // namespace fred 

En oops.cpp:

#include <string> 
#include "fred/Bar.h" 
#include "fred/Foo.h" // Oops, the meaning of Foo is now different. 

Eso es lo que la gente quiere, o soy Me falta algo?

Y tal vez usted diga que nunca debería nombrar un espacio de nombre std. Y eso está muy bien, pero ¿qué pasa con algún otro espacio de nombres de nivel raíz? ¿Debería cualquier espacio de nombre de nivel raíz que alguna vez se define en algún lugar estar siempre fuera de los límites para un nombre de espacio de nombres secundario?

Para aclarar, no consideraré ninguna respuesta que me diga que std es especial porque lo acabo de usar como ejemplo. Estoy hablando de un problema general, y estoy usando std como un accesorio para ilustrarlo, aunque admito que es un apoyo bastante sorprendente.

Respuesta

14

La razón práctica para los espacios de nombres sin uniones es que un nivel de espacios de nombres suele ser suficiente. Cuando no lo es, generalmente se usará un segundo nivel para los detalles de implementación. Y, por último, incluso cuando se utilizan múltiples niveles, todavía se suelen especificar implícitamente desde el nivel raíz. es decir. incluso dentro del espacio de nombres ns1, normalmente se referirá a ns1::ns2::foo en lugar de ns2::foo o ::ns1::ns2::foo.

Por lo tanto, por estas tres razones, el formulario ::ns1 es redundante en casos normales. El único caso en el que lo consideraría sería en envíos a Boost, porque como autor de Boost no sabré dónde se usará mi software.

+0

Voy a aceptar esta porque es lo más cercano a una respuesta real. Creo que el otro simplemente votó más alto porque era más divertido. :-) Sospecho que debería haber elegido un ejemplo diferente, o no hice la pregunta de la manera en que lo hice. – Omnifarious

2

En el caso de std no asumiría ningún otro espacio de nombres con el mismo nombre, mismas clases pero diferente significado.

En otros casos, el número :: se ve feo y dificulta la lectura del código (en mi opinión). Los conflictos de espacio de nombres son demasiado raros para poner el :: delante de todo.

3

Esto es tanto artificial:

namespace fred { 
namespace std { // A standard fred component 

class string { // Something rather unlike the ::std::string 
    // ... 
}; 

} // namespace std 
} // namespace fred 

Esta Fred no sería capaz de explicar por qué hizo eso a todo el equipo.

Para responder a su pregunta: las personas omiten primero "::" porque es un hábito, lo que ahorra tiempo y porque es más fácil esperar que cuando se utiliza el espacio de nombre en cualquier lugar, dicho nombre es absoluto, no relativo.

+3

Fred necesita ser golpeado con un LART. – user7116

7

¿por qué la gente siempre dice std ::

No siempre. Yo uso string y using ::std::string. Así que nada malo si habrá fred::std::string, porque todavía uso std::string. En pequeños archivos cpp podría ser incluso using namespace ::std.Muestra:

#include <iostream> 
using ::std::string; 
//using namespace ::std; // good for small cpp-files 

int main() 
{ 
    string s = "sometext"; // no leading ::std 
} 

usted debe nunca nombrar a un espacio de nombres std

Sí, usted no debe dar un nombre a std espacio de nombres personalizado.

2

Una gran cantidad de código está escrito en el espacio de nombres global. Si alguien realmente redefine :: std ::, no importará cómo se refiera a él en ese tipo de código.

Además, su situación es poco probable y fácil de evitar. En primer lugar, la convención desde que hubo un 'estándar' fue que usted no usa ese nombre. En segundo lugar, si tuviera que encontrar un paquete que define el espacio de nombres 'std', que acaba de hacer esto:

#include <package_name.hpp> 

namespace package_name { 
    using namespace std; 
} 

namespace my_app { 
    class my_class : public package_name::class_of_something {}; 
} 

o algo similar. Puede que tenga que nombrar explícitamente a std como std. Mi punto es este: la gente utiliza el 'estándar' no anclado todo el tiempo porque incluso las peores consecuencias no son un gran problema, y ​​es poco probable que así sea.

2

Bien, usted dice que std es solo un ejemplo. Pero a mí me parece que su pregunta solo es aplicable a un caso en el que alguien hace algo tan malo como anular std.

Permítanme dar otro ejemplo:

namespace logging 
{ 
    // Logs to local file 
} 

namespace server 
{ 
    namespace logging 
    { 
     // Logs to remote destination 
    } 
} 

namespace client 
{ 
    namespace logging 
    { 
     // Logs to local file and to screen 
    } 
} 

En este caso, no anteponiendo :: resultados en el comportamiento por defecto.

+0

Esta es una excelente razón por la cual los espacios de nombres relativos deberían usarse en algunas circunstancias, definitivamente estoy de acuerdo. – Omnifarious

+0

Pero en su clase, ¿qué sucede cuando alguien crea un espacio de nombres 'servidor' en su espacio de nombres 'cliente' para referirse a cosas relacionadas con el servidor que le preocupan al cliente? – Omnifarious

+0

@Omnifarious Solo quería mostrar que las respuestas dependen en gran medida del ejemplo que brinde para esta pregunta. De todos modos: diría que esto sería casi tan malo como inventar el propio espacio de nombres. Se podría usar "servercom" si se trata de comunicación o "serverconf" para la configuración, etc. en lugar de solo "servidor". – foraidt

33

Entonces, ¿por qué la gente dice siempre std :: en lugar de std :: ::

Probablemente porque en realidad nunca tuvieron problemas con la ambigüedad a causa de ella.

En la misma línea: nunca tuve que incluir "tierra" en mi dirección, y no voy a hacerlo.

Tienes que trazar la línea en algún lugar, y esta es una suposición razonable de que otros no crearán sus propios espacios de nombres estándar, o al menos que una biblioteca que lo haga no será muy popular. :)

+0

+1 por humor [relleno de 15 carbonos] – foraidt

+2

* risita * Bueno, si viviera en Andrómeda y quisiera referirme a alguien en la Tierra, probablemente me saltaría el 'grupo local', pero incluiría 'Vía Láctea' , 'Sol System' y 'Earth'. – Omnifarious

+2

pero la humanidad necesita evolucionar técnicamente de esta roca antes de que sea una preocupación – Hardryv

1

Del mismo modo que los nombres con el prefijo _ están reservados, considere y uno bueno como reservado.

+0

Aunque para ser pedante, no todos los nombres precedidos por un guión bajo están reservados. – GManNickG

+0

Sí, no todos. Si alguien estuviera interesado en la locura total, [lea esto] (http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) –

Cuestiones relacionadas