Ответ 1
Да, синтаксис действительно легальный, но нет, ваша функция действительно живет в пространстве имен NS. Код, который вы видите, фактически эквивалентен
namespace NS { void C::f() { /* ... } }
или
void NS::C::f() { /* ... */ }
который может быть более похожим на то, к чему вы привыкли.
Из-за директивы using вы можете опустить часть NS не только в вызове кода, но и в его определении. В стандарте приведен пример, соответствующий вашему коду (после выделенной выделенной части):
3.4.3.2 Члены пространства имен [namespace.qual]
7 В объявлении для члена пространства имен, в котором идентификатор объявления является квалифицированным идентификатором, учитывая, что квалифицированный идентификатор для пространства имен член имеет форму nested-name-specifier unqualified-id unqualified-id должен указывать член пространства имен, обозначенного вложенный имя-спецификатор или элемент встроенного пространства имен (7.3.1) этого пространства имен. [Пример:
namespace A {
namespace B {
void f1(int);
}
using namespace B;
}
void A::f1(int){ } // ill-formed, f1 is not a member of A
-end example] Однако в таких объявлениях имен пространства имен Вложенное имя-спецификатор может неявно полагаться на использование директив укажите начальную часть спецификатора вложенных имен. [Пример:
namespace A {
namespace B {
void f1(int);
}
}
namespace C {
namespace D {
void f1(int);
}
}
using namespace A;
using namespace C::D;
void B::f1(int){ } // OK, defines A::B::f1(int)
-end пример]
Таким образом, вы можете опустить начальную часть для вложенного имени-спецификатора, но не какая-либо промежуточная часть.