22

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
  • 9,209
user541686
  • 8,178

4 Answers4

28

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Јовић
  • 14,049
14

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,146
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,100
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,719