Estoy usando la declaración 'using' en C ++ para agregar std :: string y std :: vector al espacio de nombres local (para evitar escribir innecesarios 'std ::' s).
using std::string;
using std::vector;
class Foo { /*...*/ };
¿Cuál es el alcance de esta declaración? Si hago esto en un encabezado, ¿inyectará estas declaraciones de 'uso' en cada archivo cpp que incluya el encabezado?

usingdeclaración (ousingdirectiva) en el alcance del archivo en un archivo / encabezado de inclusión! Eso causará dolores de cabeza a los usuarios del encabezado.usingdeclaración ( directiva a fortiori ) en un encabezado en absoluto , ¡ incluso dentro de un espacio de nombres! Consulte el alcance de la declaración de uso dentro de un espacio de nombres para conocer los problemas que esto causa.usingen el alcance de la función y la clase es seguro con respecto al problema discutido.Respuestas:
Cuando #incluye un archivo de encabezado en C ++, coloca todo el contenido del archivo de encabezado en el lugar que lo incluyó en el archivo de origen. Entonces, incluir un archivo que tiene una
usingdeclaración tiene exactamente el mismo efecto que colocar lausingdeclaración en la parte superior de cada archivo que incluye ese archivo de encabezado.fuente
usingdeclaración dentro de unnamespace, está limitada al alcance de ese espacio de nombres, por lo que generalmente está bien (con las advertencias habituales sobre sus necesidades y estilo particulares).No hay nada especial en los archivos de encabezado que impida la
usingdeclaración. Es una simple sustitución de texto antes de que comience la compilación.Puede limitar una
usingdeclaración a un ámbito:fuente
usingdentro de una función (¡o incluso una mejorTESTmacro!) Hace que mi vida sea mucho mejor.El alcance de la declaración using depende de dónde se encuentre en el código:
fuente
usingdeclaración dentro del alcance de la clase ... Tenía la misma pregunta que el OP por eso, ya que quería evitar escribir porstd::todas partes. Obtuve clases que usan muchos vectores con punteros inteligentes y elstd::prefijo de cinco caracteres agrega mucha longitud de línea, lo que me parece que se lee peor. Entonces, me preguntaba si unausingdirectiva dentro del espacio de nombres que contiene la clase estaba bien. (Incluso si está dentro de un encabezado.)namespace { ... }?El alcance es cualquier alcance en el que se encuentre la declaración de uso.
Si este es un alcance global, entonces será de alcance global. Si está en el alcance global de un archivo de encabezado, entonces estará en el alcance global de cada archivo fuente que incluya el encabezado.
Por lo tanto, el consejo general es evitar el uso de declaraciones en el alcance global de los archivos de encabezado .
fuente
En el caso citado, el archivo ("unidad de traducción"), lo que significa que sí, todos los archivos que lo incluyen.
También puede poner la instrucción using dentro de la clase, en cuyo caso, está en efecto solo para esa clase.
Generalmente, si necesita especificar un espacio de nombres en un encabezado, a menudo es mejor calificar completamente cada identificador necesario.
fuente
usingdeclaración en una clase no se comporta de la misma manera que fuera de una clase; por ejemplo, no puede usarla encoutlugar destd::couten el ámbito de la clase.Eso es correcto. El alcance es el módulo que usa la
usingdeclaración. Si algún archivo de encabezado que incluye un módulo tieneusingdeclaraciones, el alcance de esas declaraciones será ese módulo, así como cualquier otro módulo que incluya los mismos encabezados.fuente
Hay algunos comentarios que son bastante incondicionales cuando dicen "No". Eso es demasiado severo, pero tienes que entender cuándo está bien.
Escribir
using std::stringnunca está bien. Escribirusing ImplementationDetail::Fooen su propio encabezado, cuando ese encabezado declara ImplementationDetail :: Foo puede estar bien, más aún si la declaración de uso ocurre en su espacio de nombres. P.ejfuente
MyNS::Foousing boost::posix_time::ptime. Seguro que el usuario podría escribir,MyNS::ptimepero ese no es el fin del mundo, y podría verse compensado por la conveniencia de poder tener funciones comoMyFunction(ptime a, ptime b).using std::stringnunca está bien? ¿Incluso en su propio espacio de nombres para guardar muchosstd::prefijos?