Press "Enter" to skip to content

Don’t use “using namespace std”

I’m a big fan of never using using namespace std. There are a ton of technical reasons, but I want to talk about the readability part. Generally, if it is avoided, it’s easier for somebody checking your code to see which variables are yours. Sure, cout and cin are unmistakable, but what about vector or hash or pair? Again, people will have to scroll up to see where they were declared. And they won’t find them, since they weren’t declared anywhere. If I read code, I keep track of the function and object names. If I encounter a variable I don’t know, I need to find out where it came from. And if you randomly throw the word vector into the code, it will confuse me a lot more than using std::vector, which is instantly obvious.

But what about partial imports?

Partial imports are things like using std::cout. I don’t like them. I give them out as advice for people who just won’t drop the whole using namespace std, but I personally don’t like them. If you want to use a namespace because the lines would be too long, do it locally, i.e.:

double calculate(double x) {
    using namespace std;
    return floor(sin(x)/cos(x)) + ceil(cos(x)/2);
}

void print(std::string s) {
    // using directive doesn’t apply here!
    std::cout << s << std::endl;
}

But generally I’m against the using directive. If you want it because of otherwise long names long names you have a few options:

Using auto

Quick, what does this code do?

std::vector<std::chrono::high_resolution_clock::time_point> vec;
std::vector<std::chrono::high_resolution_clock::time_point> vec2;

// fill both vectors

std::vector<std::chrono::duration<long long int, std::ratio<1, 1000000000>>> durations;

for(std::chrono::high_resolution_clock::time_point& tp : vec) {
    for(std::chrono::high_resolution_clock::time_point& tp2 : vec2) {
        std::chrono::duration<long long int, std::ratio<1, 1000000000>> dur = tp - tp2;
        std::cout << "Measured: " << dur.count() << std::endl;
        durations.push_back(dur);
    }
}

No clue? If we use auto a bunch of times (and one decltype), it will become apparent:

std::vector<std::chrono::high_resolution_clock::time_point> vec1;
std::vector<std::chrono::high_resolution_clock::time_point> vec2;

// fill both vectors

std::vector<decltype(vec1[0]-vec2[0])> durations;

for(auto& tp1 : vec1) {
    for(auto& tp2 : vec2) {
        auto dur = tp1 - tp2;
        std::cout << "Measured: " << dur.count() << std::endl;
        durations.push_back(dur);
    }
}

Not only is the code easier to read, but we also avoided using namespace std! (Even that wouldn’t have helped here, we could just have removed the first, small part. Of course, one could have used using namespace std::chrono, but that introduces yet anotherusing directive.)

Using typedef

Of course, auto comes with a lot of trouble if something is deduced incorrectly. So sometimes you need to actually explicitly give a type. One of my favorite ways to do that is using a typedef struct.

struct timer {
    typedef std::chrono::high_resolution_clock clock;
    typedef std::chrono::duration<long long int, std::ratio<1, 1000000000>> duration;
    // ...
}

Now you can use timer::clock or timer::duration instead of the long name. Generally, in my opinion, everything that isn’t declared locally should have a prefix of some sort.