Вы совершенно правы в том смысле, что 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
.
person
Christophe
schedule
17.02.2019
std
, должен быть выдворен из кампуса в тот момент, когда он делает коммит. Так что это не проблема на практике. - person n. 1.8e9-where's-my-share m.   schedule 17.02.2019