views:

99

answers:

5

Most of the research I've done on the use of using declarations, including reading relevant sections of various style guides, indicates that whether or not to use using declarations in C++ source files, as long as they appear after all #includes, is a decision left to the coder. Even the style guides I read, which usually come down on one side or the other of such common disputes for the sake of consistency, are fairly flexible in this regard.

My question is, given this high degree of flexibility, how important is it to use a consistent style? For example, suppose an author wrote something like

using std::vector;

vector<T> v;

std::cout << v[0] << std::endl;

Is the inconsistent application of using on std::vector but not std::cout or std::endl generally considered acceptable, or would it be considered undisciplined?

+7  A: 

I think the whole point of using is that you use it inconsistently among names. Names you need very frequently in some block can be declared locally with a using declaration, while others are not. I don't see a problem with that.

Declaring a name to have namespace scope is always much harder to take. I think if the name clearly is known to belong to a particular namespace so that confusing it with other namespaces won't occur, It won't hurt to put a using declaration if it makes your code more readable.

Johannes Schaub - litb
+1  A: 

Assuming you don't say using namespace std; anywhere, I don't think most developers care one way or another in other people's code. The only thing that might bother them is the overuse of the std:: qualifier --- that is if you're saying "std::vector" 20 times in the function, maybe it's time for a "using std::vector". Otherwise, no one should care.

Sometimes, in my own code, I'll use the "std::" qualifier specifically to indicate that this is the only place that I'm using that identifer.

James Curran
A: 

I try for not using using (no pun intended).

For saving typing, I like to do typedefs, e.g.:

typedef std::vector< int > IntVector;
typedef std::vector< Foo > FooVector;
ArunSaha
+2  A: 

I am now a strong proponent for explicitly stating the namespace (ie no 'using')

Most peoples namespace history goes like this (in non trivial, >100kloc projects)

Innocence -> style 1

using namespace std;

Ouch -> style 2

using std::string;
using std::vector;

OK, enough already -> style 3

std::string foo = "xxx";
pm100
@pmr100: I agree with the history, I think the first phase is most likely due to book material though, because of editorial constraints the examples shown don't general use namespaces qualifiers which both encumber the space and obscure the principle being demonstrated. Such code however is not meant to be part of a bigger program...
Matthieu M.
A: 

This is less an answer than a counterpoint to a few other answers that have advocated always explicitly including the namespace as part of the name. At times, this is a poor idea. In some cases, you want to use a name that's been specialized for the type at hand if it exists, but use a standard-provided alternative otherwise.

As a typical example, let's consider a sort function. If you're sorting some objects of type T, you're going to end up swapping items. You want to use a special swap(T &, T&) if it exists, but template <class T> std::swap otherwise.

If you try to specify the full name of the swap you're going to use explicitly, you have to specify one or the other -- either you specify a specialized version, and instantiating your sort over a type that doesn't define it's own swap will fail, or else you specify std::swap, and ignore any swap that's been provided specifically for the type you're sorting.

using provides a way out of this dilemma though:

using namespace std;

template <class T>
mysort(/* ... */ ) {

    // ...

    if (less(x[a], x[b])
        swap(x[a], x[b]);

    // ...
}

Now, if the namespace in which T is found contains a swap(T &, T&), it'll be found via argument dependent lookup, and used above. If it doesn't exist, then std::swap will be found (and used) because the using namespace std; made it visible as well.

As an aside, I think with one minor modification, using namespace x; could be made almost entirely innocuous. As it stands right now, it introduces the names from that namespace into the current scope. If one of those happens to be the same as a name that exists in the current scope, we get a conflict. The problem, of course, is that we may not know everything that namespace contains, so there's almost always at least some potential for a conflict.

The modification would be to treat using namespace x; as if it created a scope surrounding the current scope, and introduced the names from that namespace into that surrounding scope. If one of those happened to be the same as a name introduced in the current scope, there would be no conflict though -- just like any other block scoping, the name in the current scope would hide the same name from the surrounding scope.

I haven't thought this through in a lot of detail, so there would undoubtedly be some corner cases that would require more care to solve, but I think the general idea would probably make a lot of things quite a bit simpler anyway.

Jerry Coffin
For this particular usage, you could move `using namespace std;` (or rather `using std::swap;` into the function to limit its scope. - As to naming conflicts, you still can disambiguate names by qualifying them fully? Why hide that there's a conflict?
UncleBens