is "using namespace std" good style?

B

beliavsky

Many of my C++ programs have the line

using namespace std;

but the "Accelerated C++" book of Koenig and Moo has many examples
where the library names are included one at a time, for example

using std::cin;
using std::cout;

I wonder if experienced C++ programs have found that 'using' library
names explicitly is worth the bother -- what is the advantage of doing
so?
 
L

Leor Zolman

Many of my C++ programs have the line

using namespace std;

but the "Accelerated C++" book of Koenig and Moo has many examples
where the library names are included one at a time, for example

using std::cin;
using std::cout;

I wonder if experienced C++ programs have found that 'using' library
names explicitly is worth the bother -- what is the advantage of doing
so?

Just found this, evidently from this group, but undated:

http://www.janko.at/Humor/Computerwelt/using namespace std.htm

I've been one of the "guilty" ones not setting a good example; my testing
template puts "using namespace std;" up top right after including
<iostream>. This is almost always fine for my purposes, but since most of
my savings is not having type "std::" in front of cin, cout and endl, I may
as well just replace the directive with those three using declarations in
the template file...
-leor
 
J

Julie

Leor said:
Just found this, evidently from this group, but undated:

http://www.janko.at/Humor/Computerwelt/using namespace std.htm

I've been one of the "guilty" ones not setting a good example; my testing
template puts "using namespace std;" up top right after including
<iostream>. This is almost always fine for my purposes, but since most of
my savings is not having type "std::" in front of cin, cout and endl, I may
as well just replace the directive with those three using declarations in
the template file...
-leor

I'm still trying to figure out any benefit at all for using 'namespace' --
personally, I wish it weren't part of the language.
 
L

Leor Zolman

I'm still trying to figure out any benefit at all for using 'namespace' --
personally, I wish it weren't part of the language.

If I didn't end up posting a large fraction of the little test programs I
play with around here, I'd continue to use the directive up top simply to
reduce my keystroke count. Think of it as an "ergonomic" language feature
for throw-away code ;-)
-leor
 
J

Jorge Rivera

I'm still trying to figure out any benefit at all for using 'namespace' --
personally, I wish it weren't part of the language.

I don't think I understand. How would you go around including
namespaaces. Strong typing all the time?

JLR
 
J

Julie

Jorge said:
I don't think I understand. How would you go around including
namespaaces. Strong typing all the time?

Exactly.

With projects of any substantive size, you are typically dealing w/ hundreds or
thousands of symbols, in 10s of namespaces. Using 'namespace' just strips too
much information from the symbol name making current development and future
maintenance that much more difficult.

It may take a little more to initially type, but it will end up saving time
during later comprehension and maintenance. Duty now for the future.
 
D

Dietmar Kuehl

I wonder if experienced C++ programs have found that 'using' library
names explicitly is worth the bother -- what is the advantage of doing
so?

In the project I'm working on, we got roughly 20 different packages, each
of which puts their names into a separate namespace. The code is written
by a variaty of people with different tastes: some of the code uses using
declarations (ie. individual symbols are made available, eg.
'using std::cout;'), some of the code uses using directives (ie. a complete
namespace is made available, eg. 'using namespace std;', and other code uses
explicit qualification. To navigate in the code, I prefer the use of the
last option: each symbol says where it is defined. If people put using
declarations into their code, I can at least detect the units the symbols
are coming from. IMO the worst option, although the most widespread in our
project, is the use of using directives: there are many files which start
off with 10 or more using directives. Unless I know or guess which unit a
symbol is coming from, I have to look for it.

My conclusion is: using directives are worse than using declarations which
are, in turn, worse than explicit qualification. I don't mind using
directives for the standard C++ library but then, having implemented it, I
know pretty well which names there are. However, it really helps me to
locate stuff for unknown code if I can narrow down the unit it comes from.
 
S

Steven T. Hatton

Dietmar said:
In the project I'm working on, we got roughly 20 different packages, each
of which puts their names into a separate namespace. The code is written
by a variaty of people with different tastes: some of the code uses using
declarations (ie. individual symbols are made available, eg.
'using std::cout;'), some of the code uses using directives (ie. a
complete namespace is made available, eg. 'using namespace std;', and
other code uses explicit qualification. To navigate in the code, I prefer
the use of the last option: each symbol says where it is defined. If
people put using declarations into their code, I can at least detect the
units the symbols are coming from. IMO the worst option, although the most
widespread in our project, is the use of using directives: there are many
files which start off with 10 or more using directives. Unless I know or
guess which unit a symbol is coming from, I have to look for it.

This seems so blatantly obvious to me, I have to wonder how people find
justification for employing using directives. The only reason I had one in
the code I posted yesterday is because the original code had it. I was
just in the process of removing the using directives and replacing them
with using declarations. It's truly amazing the number of compiler errors
I've encountered so far due to changes in files seemingly unrelated to the
ones producing the errors.
My conclusion is: using directives are worse than using declarations which
are, in turn, worse than explicit qualification. I don't mind using
directives for the standard C++ library but then, having implemented it, I
know pretty well which names there are. However, it really helps me to
locate stuff for unknown code if I can narrow down the unit it comes from.

As a general rule I say violence is not an option when solving problems.
There are exceptions, however. ;-)
 
N

Niklas Borson

Julie said:
Exactly.

With projects of any substantive size, you are typically dealing w/ hundreds or
thousands of symbols, in 10s of namespaces. Using 'namespace' just strips too
much information from the symbol name making current development and future
maintenance that much more difficult.

It may take a little more to initially type, but it will end up saving time
during later comprehension and maintenance. Duty now for the future.

On the other hand, there are cases where you *should* specify an
unqualified name. For example, suppose you want to swap two values
a and b of type T, where T is a template parameter. You could type:

std::swap(a, b);

but this *always* invokes the swap function in the std namespace,
whereas for all you know there might be a more specialized swap for
arguments of type T. The following is better:

using std::swap;
swap(a, b);

This will call a more specialized swap if one exists, or std::swap
otherwise.
 
J

Julie

Niklas said:
On the other hand, there are cases where you *should* specify an
unqualified name. For example, suppose you want to swap two values
a and b of type T, where T is a template parameter. You could type:

std::swap(a, b);

but this *always* invokes the swap function in the std namespace,
whereas for all you know there might be a more specialized swap for
arguments of type T. The following is better:

using std::swap;
swap(a, b);

This will call a more specialized swap if one exists, or std::swap
otherwise.

If you let the compiler pick, how do you (the coder) know what is actually
happening? Seems to me like a bad idea -- I feel that we tell the compiler
(specifically) what to do, not leave it open ended like that.

Comments?
 
S

Steven T. Hatton

Julie said:
Niklas Borson wrote:

If you let the compiler pick, how do you (the coder) know what is actually
happening? Seems to me like a bad idea -- I feel that we tell the
compiler (specifically) what to do, not leave it open ended like that.

Comments?

I'm not even sure the original assertion is correct. I am under the
impressionn that a using declaration will hide other instances of the
symbol so that using std::swap; will cause only std::swap() to be invoked
unless the other swap is specifically qualified.
 
S

Steven T. Hatton

Steven said:
Julie wrote:

I'm not even sure the original assertion is correct. I am under the
impressionn that a using declaration will hide other instances of the
symbol so that using std::swap; will cause only std::swap() to be invoked
unless the other swap is specifically qualified.

What does this indicate?

#include <iostream>

using std::eek:stream;
using std::endl;

namespace assign_f {
float calc(float x, float y)
{
return x * y ;
}
}

namespace assign_i {
int calc(int x, int y)
{
return x + y;
}
}

namespace assign {
int acalc(int x, int y)
{
return x - y;
}

float acalc(float x, float y)
{
return y!=0? x/y: 0;
}
}

void t1(ostream& out,
const int& i1,
const int& i2,
const float& f1,
const float& f2 ) {
using assign_i::calc;

int i = calc(i1,i2);
out << i << endl;
float f = calc(f1,f2);
out << f << endl;

}

void t2(ostream& out,
const int& i1,
const int& i2,
const float& f1,
const float& f2 ) {

using assign_f::calc;
int i = calc(i1,i2);
out << i << endl;
float f = calc(f1,f2);
out << f << endl;
}

void t3 (ostream& out,
const int& i1,
const int& i2,
const float& f1,
const float& f2 ) {

using assign::acalc;

int i = acalc(i1,i2);
out << i << endl;
float f = acalc(f1,f2);
out << f << endl;
}

int main(int argc, char* argv[]) {
using std::cout;

int i1 = 10;
int i2 = 8;
float f1(i1);
float f2(i2);

t1(std::cout, i1,i2,f1,f2);
t2(std::cout, i1,i2,f1,f2);
t3(std::cout, i1,i2,f1,f2);
}
hattons@ljosalfr:~/code/c++/scratch/assign/src/
Wed May 26 17:16:39:> g++ -o assign main.cc
main.cc: In function `void t1(std::eek:stream&, const int&, const int&, const
float&, const float&)':
main.cc:41: warning: passing `const float' for argument passing 1 of `int
assign_i::calc(int, int)'
main.cc:41: warning: argument to `int' from `const float'
main.cc:41: warning: passing `const float' for argument passing 2 of `int
assign_i::calc(int, int)'
main.cc:41: warning: argument to `int' from `const float'
main.cc: In function `void t2(std::eek:stream&, const int&, const int&, const
float&, const float&)':
main.cc:53: warning: initialization to `int' from `float'
main.cc:53: warning: argument to `int' from `float'
hattons@ljosalfr:~/code/c++/scratch/assign/src/
Wed May 26 17:17:15:>./assign
18
18
80
80
2
1.25
 
S

Steven T. Hatton

Steven T. Hatton wrote:

Sorry, I neglected to add one important element. Add the two last lines
after namespace assign, as indicated:

namespace assign {
int acalc(int x, int y)
{
return x - y;
}

float acalc(float x, float y)
{
return y!=0? x/y: 0;
}
}

using namespace assign_f;
using namespace assign_i;
 
D

David Rubin

In the project I'm working on, we got roughly 20 different packages, each
of which puts their names into a separate namespace.

If you use Lakos-style registered package names, this issue is moot. A
fully qualified name such as might appear in the declaration

AcmeCorp::bdet_List<int> list;

indicates *immediately* to the reader that the component is provided
by AcmeCorp (e.g., as opposed to boost, ACE, etc), and is implemented
in the files

$acme/bde/bdet/bdet_list.h
$acme/bde/bdet/bdet_list.cpp

where $acme is the location of the AcmeCorp distribution.
[...] some of the code uses using directives (ie. a complete
namespace is made available, eg. 'using namespace std;', and other code uses
explicit qualification. To navigate in the code, I prefer the use of the
last option: each symbol says where it is defined.

Using individual namespaces, the above example might degenerate to

AcmeCorp::bde::bdet::List<int> list;

which borders on the ridiculous. As far as

using namespace AcmeCorp;

is concerned, this makes most sense within implementation files in the
AcmeCorp distribution. There is little chance that the symbol
'bdet_List' will be defined in another namespace. Furthermore,
AcmeCorp implementation files always use namespace-qualified symbols
from external libraries such as std::, boost::, etc. For that matter,
if you are *only* using AcmeCorp libraries in your application, there
does not seem to be much value in typing AcmeCorp:: all the time.
My conclusion is: using directives are worse than using declarations which
are, in turn, worse than explicit qualification. I don't mind using
directives for the standard C++ library but then, having implemented it, I
know pretty well which names there are. However, it really helps me to
locate stuff for unknown code if I can narrow down the unit it comes from.

As far as 'using namespace std;' is concerned, I generally avoid it,
if for no other reason than that the types are difficult (for me) to
distinguish because their names are in all lower-case.

/david
 
D

Denis Remezov

Dietmar said:
In the project I'm working on, we got roughly 20 different packages, each
of which puts their names into a separate namespace. The code is written
by a variaty of people with different tastes: some of the code uses using
declarations (ie. individual symbols are made available, eg.
'using std::cout;'), some of the code uses using directives (ie. a complete
namespace is made available, eg. 'using namespace std;', and other code uses
explicit qualification. To navigate in the code, I prefer the use of the
last option: each symbol says where it is defined. If people put using
declarations into their code, I can at least detect the units the symbols
are coming from. IMO the worst option, although the most widespread in our
project, is the use of using directives: there are many files which start
off with 10 or more using directives. Unless I know or guess which unit a
symbol is coming from, I have to look for it.

My conclusion is: using directives are worse than using declarations which
are, in turn, worse than explicit qualification. I don't mind using
directives for the standard C++ library but then, having implemented it, I
know pretty well which names there are. However, it really helps me to
locate stuff for unknown code if I can narrow down the unit it comes from.

In regards to namespaces in general (not std):
I am quite convinced that there is one scenario (aside from implementing
kludges and work-arounds) in which the use of a using directive is justified.
I'm interested to hear others' opinions, nevertheless.

Let's say a file (not a header file!) contains the implementation of a
specific isolated functionality declared in namespace ABC. The focus is
namespace ABC, anything else is just to support the implementation.
In this case, explicit qualification may be supefluous. I'd put

using namespace ABC;

at the top of the file, just after the #include-s; no other using
directives are present.

The right circumstances: what gets included into the global scope is
controlled. The global scope will consist of well-known definitions,
the amount of which will often be small. Most of the name variety comes
packaged in respective namespaces.
In this scenario, name clashes could be just freak occurrences.

Denis
 
M

Michiel Salters

Julie said:
If you let the compiler pick, how do you (the coder) know what is actually
happening? Seems to me like a bad idea -- I feel that we tell the compiler
(specifically) what to do, not leave it open ended like that.

Sorry, but you can't. Notice the qualification :
"a and b of type T, where T is a template parameter". How do you know
what swap is best, if you don't know the applicable types?

Koenig lookup is designed for this; it will search for a swap in T's
namespace. However, std::swap should be used as a default when no
other swap is found. It's a template, so it won't be chosen if a
usable non-template swap is found.

Regards,
Michiel Salters
 
S

Steven T. Hatton

David said:
(e-mail address removed) (Dietmar Kuehl) wrote in message

If you use Lakos-style registered package names, this issue is moot. A
fully qualified name such as might appear in the declaration

AcmeCorp::bdet_List<int> list;

indicates *immediately* to the reader that the component is provided
by AcmeCorp (e.g., as opposed to boost, ACE, etc), and is implemented
in the files

$acme/bde/bdet/bdet_list.h
$acme/bde/bdet/bdet_list.cpp

This has naming convention has advantages if one wants to automate the
process of symbol lookup at edit time. To my mind, this is clearly a good
approach. I've suggested as much for /namespace std::/, as well as for
other namespaces and libraries.
where $acme is the location of the AcmeCorp distribution. [...]
Using individual namespaces, the above example might degenerate to

AcmeCorp::bde::bdet::List<int> list;

which borders on the ridiculous. As far as

using namespace AcmeCorp;

I tend to favor more deeply structured naming hierarchies. There is more
reason to arrange information in nested structures than collision
avoidance. The advantages of doing so are clearly reflected in the Bible
and the Rig Veda, which both have exhibit a significant formal structure.
This tried and true ancient structure is present in the the macros used to
identify the sections of the International Standard ISO/IEC 14882-2003,
Programming Languages - C++, Why that seems not to have been (well)
preserved in the structure of the actualy Standard Library, is beyond me.
is concerned, this makes most sense within implementation files in the
AcmeCorp distribution. There is little chance that the symbol
'bdet_List' will be defined in another namespace. Furthermore,
AcmeCorp implementation files always use namespace-qualified symbols
from external libraries such as std::, boost::, etc. For that matter,
if you are *only* using AcmeCorp libraries in your application, there
does not seem to be much value in typing AcmeCorp:: all the time.
As far as 'using namespace std;' is concerned, I generally avoid it,
if for no other reason than that the types are difficult (for me) to
distinguish because their names are in all lower-case.

/david

I really haven't attempted this, but the concept of anonymous namespaces
suggest an approach in which one could introduce a symbol with a using
declaration and be confident it was not inadvertantly spilled into another
namespace. I don't know what the negative consequences of such a practice
would be. Currently I am much inclined to putting using declarations at
the top of the files in which the names are used. If I have to list 15
such names, I prefer that to a using directive. For one thing, it informs
the reader of what the contained code depends on. Names which don't appear
in that list of declarations, but do appear in the file are to be
understood as defined locally. I will occasionally use something such
as /std::vector/, inplace, but that is probably an exercise in lazyness
which undermines the strenth of the approach I've described.
 
N

Niklas Borson

Sorry, but you can't. Notice the qualification :
"a and b of type T, where T is a template parameter". How do you know
what swap is best, if you don't know the applicable types?

Yes, exactly. In the case of template code, the *user* of the
code is in a better place to know which swap is best than the
implementor.

For example, if I've defined a specialized swap function for
MyType then I would expect std::sort<MyType*,MyType*> to call
my swap function instead of std::swap. I believe that is what
the standard requires.
Koenig lookup is designed for this; it will search for a swap in T's
namespace. However, std::swap should be used as a default when no
other swap is found. It's a template, so it won't be chosen if a
usable non-template swap is found.

Or for that matter are "more specialized" template swap.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top