Что означает, если пространство имен в C ++ квалифицируется с помощью ::
? Например :: testing :: Test
.
::
— оператор разрешения области видимости. Это всегда означает «поиск символа справа в глобальном пространстве имен». Например:
namespace testing {
int a = 1;
}
namespace foo {
namespace testing {
int a = 2;
}
int b = ::testing::a; // b has the value 1
int c = testing::a; // c has the value 2
}
Если ::
используется слева, это означает глобальную область действия.
Если вам нужна аналогия с файловой системой, testing::Test
будет своего рода относительным путем (относительно König lookup), тогда как ::testing: :Test
будет абсолютным путем. Я надеюсь, что эта аналогия сделает это более ясным и не запутает ваш разум :-).
Если перед именем переменной поставить ::, переменная преобразуется в глобальную область. Таким образом, вы можете проводить как тестирование локальных переменных, так и тестирование глобальных переменных и различать их.
#include <iostream>
using namespace std;
int testing = 37;
int main()
{
int testing = 42;
cout << ::testing << ' ' << testing << endl;
}
Вывод будет 37 42
Это означает, что пространство имен testing
, на которое ссылаются, является пространством имен, а не другим вложенным пространством имен с именем testing
.
Рассмотрим следующий угловой случай и, вероятно, пример плохого дизайна:
namespace foo
{
struct gizmo{int n_;};
namespace bar
{
namespace foo
{
float f_;
};
};
};
int main()
{
using namespace foo::bar;
::foo::gizmo g;
g.n_;
}
Есть 2 пространства имен с именем foo
. Один из них находится на верхнем уровне, висящем в «глобальном» пространстве имен, а другой вложен в foo::bar
. затем мы переходим к с использованием пространства имен foo::bar
, что означает, что любая безоговорочная ссылка на gizmo
подхватит ссылку в foo::bar::foo
. Если мы действительно хотим тот, который находится в foo
, то мы можем использовать для этого явную квалификацию:
::foo::gizmo
Это вызывает нечто, называемое полным поиском имени:
$3.4.3/1 - "На имя класса или члена пространства имен можно ссылаться после :: разрешения области видимости оператор (5.1), применяемый к спецификатору вложенного имени, который назначает его класс или пространство имен. Во время поиска имени, предшествующего оператору разрешения ::, имена объекта, функции и перечислителя игнорируются. Если найденное имя не является имя-класса (пункт 9) или имя-пространства-имен (7.3.1), программа имеет неправильный формат."