Просто небольшое дополнение.Как сказал конструктор, квалифицированный поиск всегда генерирует правильно сформированный код, но этот код не всегда дает ожидаемый результат.Рассмотрим этот пример устранения неоднозначности
#include <iostream>
void foo();
void foo(float);
namespace Boo {
using ::foo;
void foo(int a) { std::cout << __PRETTY_FUNCTION__ << " is here!\n"; }
}
void foo() { std::cout << __PRETTY_FUNCTION__ << " is here!\n"; }
void foo(int a) { std::cout << __PRETTY_FUNCTION__ << " is here!\n"; }
void foo(float) { std::cout << __PRETTY_FUNCTION__ << " is here!\n"; }
using namespace Boo;
int main(int argc, char *argv[])
{
foo(); // no error!
Boo::foo(); // still same
//foo(3); // aw, there are three of them. Bad, bad `using namespace`!
Boo::foo(3);
Boo::foo(3.f);
return 0;
}
пространство имен Boo
, в котором имя foo
распространяется на Boo::foo
.Мы определили foo()
после объявления пространства имен, но объявление прототипа должно было быть известно раньше.
Теперь представьте, что Boo
- это std
, foo
прототипы - это что-то вроде abs
или sin
из стандартного заголовка, и они объявлены таким образом.Реализации заголовка могут использовать трюк сверху.Результат переопределения имен, используемых в стандартном пространстве имен, описывается как неопределенный, потому что в зависимости от того, была ли using
в реализации или нет, программа будет использовать стандартную или пользовательскую функцию без учета квалифицированного имени.
TL; DR: результат квалифицированного поиска всегда верен, но не всегда является точным, если зарезервированные имена не соблюдаются.