Я считаю более целесообразным окружить весь код, который должен находиться в пространстве имен, в блоке namespace a { ... }
, поскольку это семантически то, что вы делаете: вы определяете элементы в пространстве имен a
. Но если вы только определяете членов, тогда обе вещи будут работать.
Когда компилятор найдет void my::foo()
, он попытается определить, что такое my
, и найдет using a::my
, разрешит my
из этого и поймет, что вы определяете метод a::my::foo
.
С другой стороны, этот подход потерпит неудачу, если вы используете бесплатные функции:
// 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 ) {
//....
}
Компилятор с радостью переведет приведенный выше код в программу, но фактически он объявляет std::ostream& a::operator<<( std::ostream&, a::my const & )
в заголовочном файле - без реализации - и определяет std::ostream& ::operator<<( std::ostream &, a::my const & )
в файле cpp, который является другая функция. Используя поиск Кенинга, всякий раз, когда компилятор видит cout << obj
с obj
типа a::my
, компилятор будет искать во вложенных пространствах имен cout
и my
(std
и a
) и найдет что a::operator<<
объявлено, но никогда не определено в namespace a
. Он скомпилирует, но не скомпонует ваш код.