Так что же на самом деле происходит в коде? X * p превращается в X::X*
p?
В основном. Правила поиска имени начинаются в самой узкой области. Когда вы делаете X* p;
в f
, он смотрит в область действия f
и ничего не находит. Затем он проверяет область действия X
, поскольку f
ограничен X
. Он находит X
, поскольку он внедряется в область видимости класса, поэтому останавливается там, и вы получаете тип класса.
Когда вы делаете ::X* q;
, тогда ::X
говорит, что ищет X
в глобальном пространстве имен и там находит переменную, а не тип, поэтому вы получаете ошибку.