cppaddict wrote:
I'm curious about the pros and cons of using the std:: prefix versus
the "using namespace std;" directive.
Obviously the directive saves you some typing, but I seem to remember
reading somewhere that it is not good form. Maybe because it is not
immediatly apparent which objects are part of the standard libraries
and which are your own.
Does anyone have additional thoughts on the matter or know what the
expert consensus is, assuming there is one?
The "expert consensus" is that using directives are bad. I think
there's a lot of misunderstanding about them, though, and while I don't
always use them, I think they are undervalued.
Using directives do not introduce anything into the current namespace.
They only make things in other namespaces available, if no local version
has been defined. This is very similar to the way that variable
declarations in an inner scope mask similar declarations in outer scopes.
A line like "using namespace defaults;" tells the compiler, "if I use a
function named foo, and there's a locally declared foo, use it, but if
there's no locally declared version, here's a good place to look for a
default." This and Koenig lookup can help make sure you always get the
best (most specialized) default versions of things. If there's ever a
conflict between Koenig and a using directive, the compiler will let you
know, and you just add a using declaration to remove the ambiguity.
This is similar to the way such a declaration can be provided in a
subclass to disambiguate use of an identifier declared in multiple base
classes. If you explicitly use std::some_function all the time, you'll
miss out on any local overloads of some_function.
#include <iostream>
namespace udts
{
struct Udt { };
void print( Udt ) { std::cout << "udts::print\n"; }
}
namespace defaults
{
void foo ( ) { std::cout << "defaults::foo\n"; }
void bar ( ) { std::cout << "defaults::bar\n"; }
void print( udts::Udt ) { std::cout << "defaults::print\n"; }
}
namespace local
{
void bar ( ) { std::cout << "local::bar\n"; }
void f ( )
{
using namespace defaults;
bar( ); // Local bar.
foo( ); // Defaults to defaults::foo.
using udts::print;
// The using directive conflicts with Koenig, so the
// compiler will give an error about ambiguity if this
// declaration is not provided.
print( udts::Udt( ) ); } }
int main ( )
{
local::f ( );
}