Considero más apropiado rodear todo el código que debe estar en el espacio de nombres dentro de un bloque namespace a { ... }
, ya que eso es semánticamente lo que estás haciendo: estás definiendo elementos dentro del espacio de nombres a
. Pero si solo está definiendo miembros, entonces ambas cosas funcionarán.
Cuando el compilador encuentra void my::foo()
, se tratará de determinar lo que es my
, y que se encuentra el using a::my
, resolver my
de eso y entender que va a definir el método a::my::foo
.
Por otra parte este enfoque fallará si está utilizando funciones gratuitas:
// header
namespace a {
class my { // ...
};
std::ostream & operator<<(std::ostream& o, my const & m);
}
// cpp
using a::my;
using std;
ostream & operator<<(ostream & o, my const & m) {
//....
}
El compilador estará feliz de traducir el código anterior en un programa, pero lo que está haciendo en realidad se declara std::ostream& a::operator<<(std::ostream&, a::my const &)
en la cabecera file --without implementation-- y definiendo std::ostream& ::operator<<(std::ostream &, a::my const &)
en el archivo cpp, que es una función diferente. Uso de la búsqueda Koening, siempre que el compilador ve cout << obj
con obj
de tipo a::my
, el compilador buscará en los espacios de nombres de cerramiento de cout
y my
(std
y a
) y encontrará que hay una a::operator<<
declarados pero nunca definido en namespace a
. Recopilará pero no vinculará su código.
+1. Lo que está en el espacio de nombres está en 'namespace {}'. Cosas como esta no requieren indentación así que realmente no hay problemas. – Potatoswatter