To understand the words, it is necessary to understand what a using
directive like using namespace std
does.
When it sees a name like vector
the compiler, by default, looks for vector
within the current context (i.e. in your example, that is in the "global namespace" or, equivalently in ::
). If it doesn't find a candidate match (i.e. something named vector
) in that search it issues a diagnostic, and compilation ceases.
The using namespace std
causes the compiler to look in namespace std
for matching names. If it finds an unambiguous match then that name is used.
The problem comes in if there is another using
directive, such as using namespace foo
in effect. For example;
using namespace std;
#include "foo.h"
using namespace foo;
#include "median.h"
Now consider what happens if foo.h
specifies a templated something named vector
within namespace foo
. Assume that median.h
has
double median(vector<double>);
Because of the two using
directives, the compiler looks in both std
and foo
for a name vector
. If it finds a match in both namespaces, then it has two candidate matching names, foo::vector
and std::vector
.
If both of those names are equally good matches to vector
, then the code has a diagnosable error due to ambiguity. The compilation will fail. There is no rule that makes the compiler consider a match in namespace std
is better than one in namespace foo
, or vice versa.
The next problem is that there is no way to undo the effect of a using
directive (e.g. with other using
directives or declarations). The only way to get the code to compile in such a case is to change the declaration of median()
to
double median(std::vector<double>);
Rather than going through all of that, Koenig and Moo are advocating using the full name std::vector<double>
from the start, rather than messing with using
directives in the header. Doing that allows other programmers, who use the header file, to employ using
directives or declarations if they choose, but does not require them to do so.
Note: the above is an over-simplification. There are quite a few detailed rules that govern how a compiler finds candidates names, and then determines how good a match they are.