Основной интерес представляет то, в чем различия с точки зрения компилятора, как уже было сказано, если вы включаете ::
, то вы используете квалифицированный поиск, а не неквалифицированный поиск.
Преимущество использования квалифицированного поиска состоит в том, что он всегда сможет точно определить конкретный символ.Недостатком является то, что он всегда точно определяет этот конкретный символ - то есть он отключает Argument Dependent Lookup.ADL является большой и полезной частью языка, и, квалифицируя, вы фактически отключаете его, и это плохо.
Учтите, что у вас есть функция f
в глобальном пространстве имен и что вы добавили типT
внутри пространства имен N
.Не считайте, что вы хотели добавить перегрузку f
, которая бы принимала T
в качестве аргумента.Следуя принципу interface , вы можете добавить f
к пространству имен N
, поскольку f
на самом деле является операцией, выполняемой над T
, и поэтому относится к типу.В этом случае, если у вас был код, который вызывал (рассмотрим универсальный код) ::f(obj)
для объекта неизвестного типа U
, компилятор не сможет принять ::N::f(obj)
в качестве потенциальной перегрузки, поскольку код явно запрашиваетперегрузка в глобальном пространстве имен.
Использование неквалифицированного поиска дает вам свободу определения функций, которым они принадлежат, вместе с типами, которые используются в качестве аргументов.Хотя это не совсем то же самое, рассмотрите возможность использования swap
, но если вы квалифицируетесь std::swap
, он не поднимет вашу руку, брошенную void swap( T&, T& )
в ваше N
пространство имен ...
Iбудет полностью квалифицировать идентификаторы только тогда, когда компилятор не получит нужный элемент.