Вы совершенно правы в том смысле, что yyyy::xxx
может быть неоднозначным, если есть пространство имен yyyy
, а также класс yyyy
, которые оба видны в одной и той же области видимости.В этом случае только полная квалификация ::yyyy::xxx
может решить неоднозначность.Пример вашей ссылки проясняет это:
// from cppreference.com
#include <iostream>
int main() {
struct std{};
std::cout << "fail\n"; // Error: unqualified lookup for 'std' finds the struct
::std::cout << "ok\n"; // OK: ::std finds the namespace std
}
Но на практике сложно создать конфликтующий std
на верхнем уровне, так как большинство включений из стандартной библиотеки приведут к сбою:
#include <iostream>
struct std { // OUCH: error: ‘struct std’ redeclared as different kind of symbol
int hello;
};
Это означает, что для создания конфликта вам необходимо определить локальные классы или ввести предложение using
в другом пространстве имен.Кроме того, никто не посмеет (смел) назвать класс std
.
Наконец, на практике ::yyyy::xxx
менее удобно читать.Все это объясняет, почему вы не найдете его очень часто.
Дополнительное замечание
Проблема не столько в std
, который хорошо известен, а скореедля ваших собственных пространств имен и сторонних библиотек.В этом случае псевдоним пространства имен будет лучшей альтернативой :::yyyy
для устранения неоднозначности:
namespace foo {
void printf() { }
}
int main() {
foo::printf(); // ok, namespace is chose because no ambiguity
struct foo {/*...*/ }; // creates ambiguity
//foo::printf(); // error because struct foo is chosen by name lookup
::foo::printf(); // ok, but not if you decide to move the code to be nested in another namespace
namespace mylib = foo ; // or ::foo (see discussion below)
mylib::printf(); // full flexibility :-)
}
Его преимуществом является более высокая гибкость.Предположим, например, что вы переместили бы свой код, чтобы вложить его во вложенное пространство имен.С псевдонимом пространства имен ваш код может продолжать работать как есть (в худшем случае с незначительными изменениями в определении псевдонима).С разрешением глобальной области видимости вам придется изменить все операторы, в которых будет использоваться глобальное пространство имен ::foo
.