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?
using
declaración (ousing
directiva) en el alcance del archivo en un archivo / encabezado de inclusión! Eso causará dolores de cabeza a los usuarios del encabezado.using
declaració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.using
en 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
using
declaración tiene exactamente el mismo efecto que colocar lausing
declaración en la parte superior de cada archivo que incluye ese archivo de encabezado.fuente
using
declaració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
using
declaración. Es una simple sustitución de texto antes de que comience la compilación.Puede limitar una
using
declaración a un ámbito:fuente
using
dentro de una función (¡o incluso una mejorTEST
macro!) 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
using
declaració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 unausing
directiva 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
using
declaración en una clase no se comporta de la misma manera que fuera de una clase; por ejemplo, no puede usarla encout
lugar destd::cout
en el ámbito de la clase.Eso es correcto. El alcance es el módulo que usa la
using
declaración. Si algún archivo de encabezado que incluye un módulo tieneusing
declaraciones, 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::string
nunca está bien. Escribirusing ImplementationDetail::Foo
en 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::Foo
using boost::posix_time::ptime
. Seguro que el usuario podría escribir,MyNS::ptime
pero 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::string
nunca está bien? ¿Incluso en su propio espacio de nombres para guardar muchosstd::
prefijos?