Когда вы делаете это:
void C::f()
{
#pragma message( "Compiling " __FUNCTION__ )
}
f
здесь - это квалифицированное имя (квалифицированное C
). Таким образом, C ++ должен выяснить, о чем C
вы говорите. Для этого ему нужно посмотреть доступные неквалифицированные имена и найти в них идентификатор C
. Поскольку вы находитесь в пространстве имен A
, а в пространстве имен A
было выгружено все пространство имен B
, C
преобразуется в A::B::C
. И, таким образом, C::f
становится A::B::C::f
.
В отличие от этого, когда вы делаете это:
void g()
{
#pragma message( "Compiling " __FUNCTION__ )
}
g
является неквалифицированным именем . Таким образом, это имя означает именно то, что оно говорит: имя g
в текущем пространстве имен. Это объявления A
.
using
не изменяют текущее пространство имен;это только изменяет правила поиска имени для имен. Поскольку g
- безусловное имя, искать нечего;Вы имели в виду A::g
.
Это означает, что вы не определяете функцию A::B::g
.
Итак, у вас есть заголовок с надписью "Я обещаю, что кто-тогде-то определит A::B::g
, "но никто на самом деле не делает. source.cpp
только определил A::g
, который main.cpp
не пытается вызвать (поскольку он не подозревает, что он существует).
Отсюда ошибка компоновщика.