The main point of interest is what the differences are from the point of view of the compiler, as it has already been said, if you include the ::
then you are using qualified lookup, rather than unqualified lookup.
The advantage of using qualified lookup is that it will be able to pinpoint a particular symbol always. The disadvantage is that it will always pinpoint that particular symbol --i.e. it will disable Argument Dependent Lookup. ADL is a big and useful part of the language, and by qualifying you effectively disable it, and that is bad.
Consider that you had a function f
in the global namespace, and that you added a type T
inside namespace N
. Not consider that you wanted to add an overload of f
that would take a T
as argument. Following the interface principle, you can add f
to the N
namespace, as f
is actually an operation performed on T
, and it so belongs with the type. In this case, if you had code that called (consider generic code) ::f(obj)
on an object of unknown type U
the compiler will not be able to pick up ::N::f(obj)
as a potential overload as the code is explicitly asking for an overload in the global namespace.
Using unqualified lookup gives you the freedom of defining the functions where they belong, together with the types that are used as arguments. While it is not exactly the same, consider the use of swap
, if you qualify std::swap
then it will not pick up your hand rolled void swap( T&, T& )
inside your N
namespace...
I would only fully qualify identifiers when the compiler would otherwise not pick up the element I want.