20

Discounting subtly different semantics due to ADL, how should I generally use using, and why? Is it situation-dependent (e.g. header which will be #included vs. source file which won't)?

Also, should I prefer ::std:: or std::?

  1. Namespace-level using namespace:

    using namespace std;
    
    pair<string::const_iterator, string::const_iterator>
    f(const string &s) {
        return make_pair(s.begin(), s.end());
    }
    
  2. Being fully explicit:

    std::pair<std::string::const_iterator, std::string::const_iterator>
    f(const std::string &s) {
        return std::make_pair(s.begin(), s.end());
    }
    
  3. Namespace-level using-declarations:

    using std::pair;
    using std::string;
    
    pair<string::const_iterator, string::const_iterator>
    f(const string &s) {
        return make_pair(s.begin(), s.end());
    }
    
  4. Function-local using-declarations:

    std::pair<std::string::const_iterator, std::string::const_iterator>
    f(const std::string &s) {
        using std::make_pair;
        return make_pair(s.begin(), s.end());
    }
    
  5. Function-local using namespace:

    std::pair<std::string::const_iterator, std::string::const_iterator>
    f(const std::string &s) {
        using namespace std;
        return make_pair(s.begin(), s.end());
    }
    
  6. Something else?

This is assuming pre-C++14, and thus no return-type-deduction using auto.

Deduplicator
  • 8,591
  • 5
  • 31
  • 50
user541686
  • 8,074
  • 8
  • 38
  • 49
  • 2
    See http://stackoverflow.com/questions/1265039/using-std-namespace for a starting point. – AProgrammer Mar 24 '12 at 07:45
  • @AProgrammer: Ah, thanks for the link, that answers part of my question. :) Still wondering about `::std::` vs. `std::` though. – user541686 Mar 24 '12 at 07:49
  • 4
    I'm using `std` without second though. Someone defining a std namespace is asking for trouble (and probably searching to take advantage that most people are using `std` and not `::std`). – AProgrammer Mar 24 '12 at 11:35

4 Answers4

27

Avoid using using in headers, because that breaks the purpose of namespaces.

It is ok to use it in source files, but I would still avoid it in some cases (for example using std).

However if you got nested namespaces, it's ok :

namespace A {
namespace B {
namespace C {
class s;
} // C
} // B
namespace D{
using B::C::s;
} // D
} // A
BЈовић
  • 13,981
  • 8
  • 61
  • 81
  • 6
    +1 it's amazing how many tutorials and college courses just tell you to use the `using` keyword without a thorough explanation of why namespaces are used to begin with. – Jeffrey Sweeney Mar 24 '12 at 13:19
  • People want to get on with using iostreams, strings, and so on. They don't want to have to type std:: every single time they want to use a thing, or have to remember yet another piece of boilerplate to put before their code, which will cause less-than-helpful errors if they forget it. :( – Colen Mar 24 '12 at 20:34
  • Would something like typedef std::string sstring; be an alternative? – Giorgio Jun 17 '12 at 09:16
  • @Giorgio Yes, but that is something else. With typedef, you do not get type name clash. – BЈовић Jun 18 '12 at 05:37
  • That's why I was suggesting it. – Giorgio Jun 18 '12 at 05:38
  • 1
    @Colen: These poor souls can use `using std::cout` and friends, but it's not like `cout` is already a horribly long name. – Benjamin Bannier Aug 03 '12 at 11:43
  • 1
    If you're a college student in your first day of "my first C++ class", it's yet another thing that can cause syntax errors that you don't understand. It's easy for us to figure out because we're experienced programmers, but when you're trying to learn the language, it's yet another thing to have to worry about that you don't need. – Colen Aug 03 '12 at 18:00
  • Wasn't "using C::B::s;" supposed to be "using B::C::s;" ? – Artur Mar 14 '19 at 09:42
13

When putting a using statement in a source file, PLEASE, just pull in the things you need. For instance:

using std::string;
using std::ostringstream;

The issue here is that if you do

using namespace std;

you pull in EVERY SINGLE THING from std into the global namespace. Which leads to very interesting error messages when you accidentally use a name in your code that matches one you were completely unaware of in std. If you just pull in the stuff you want, then you won't have that problem (or, more precisely, the next programmer to work on your code won't have that problem).

Michael Kohne
  • 10,038
  • 1
  • 36
  • 45
  • 1
    Alternatively, you can `using namespace` just in a function scope, avoiding the issue. – Tamás Szelei Aug 03 '12 at 11:58
  • 3
    @fish - actually, doing 'using namespace' in function scope doesn't avoid the issue, it just limits the space where things can go wrong. And if you end up putting 'using namespace' in every function, it's not much different from just doing it globally. – Michael Kohne Aug 03 '12 at 12:47
  • While C++ indeed does allow one to declare types on the function level, it is not a common thing; other than that, the possible name clashes are easy to spot from the compiler output (but you are right that this does not prevent them). – Tamás Szelei Aug 03 '12 at 15:02
4

As VJovic indicates, do not use using in a header file. using in a header file affects the current compilation unit (the .cpp file) in ways that the source file may not be expecting.

using namespace is also to be avoided in a source file. This brings every symbol into the same scope as the source file. It is more clear to your readers what you are doing if you use specific symbols from the namespace.

Bill Door
  • 1,090
  • 8
  • 8
  • 2
    As a practical concern, unless your code overrides commonly-used names, I'd much rather see `using namespace JoystickModule` at the beginning of a .cpp file than `JoystickModule::` attached to every object throughout. – Alex P Jun 03 '12 at 16:29
  • @AlexP: That's exactly how I do it. One `using` statement for my own namespace I'm currently working on and everything else stays namespaced. – Benjamin Kloster Aug 03 '12 at 11:25
  • I should elaborate on "use specific symbols from the namespace". Rather than prefixing each symbol on every use, which does not help with readability, I prefer to use explicit symbol hoisting. `using SomeNameSpace::SomeSymbol`. This avoids moving every symbol from the the namespace into the current scope. – Bill Door Sep 07 '12 at 16:45
1

Writing using in Headers is the best way to create all kinds of nasty and impossible to debug bugs. Do not do this.

Writing using namespace XYZ in the source file is a little better, but can still cause you countless headaches. The safe way is to explicitely specify what you are using e.g. using Foo::Bar.

Let's say you have Bar.cpp with the following:

//Bar.cpp
using namespace Foo;
namespace
{
    double increment(double v) { return (v + 1); }
}

void Bar::someFunction()
{
    //...
    int currentIndex = 0;
    int nextIndex = increment(currentIndex);
    //...
}

The function worked fine, until one day - seemingly without any code changes in relevant classes - its behaviour changed: Suddenly currentIndex always seems to be off by one. Digging through the recent changes you discover no changes even remotely related to the code.

Eventually you discover the cause:
You (indirectly) include Foo.h somewhere. In the files for the Foo namespace a new function was added:

//Foo.h
namespace Foo
{
    //...
    int& increment(int& v) { v += 1; return v; };
    //...
}

Which is an unambigiously better match for increment(int) than your function increment(double) - so now Foo::increment() function is called by Bar::someFunction() instead. Whoops.

(And if you were to write using in Headers that using namespace Foo might very well be anywhere in your include tree...)

So... Don't write any using in Headers, and also be wary of writing using namespace in source files.

CharonX
  • 1,633
  • 1
  • 11
  • 23