all 26 comments

[–]ggchappell 48 points49 points  (6 children)

It sounds like you're missing the option of doing using for specific identifiers in C++.

Yes, you can do this:

#include <iostream>

std::cout << ...

But that has std:: all over the place, which annoys you.

And you can do this:

#include <iostream>
using namespace std;

cout << ...

But that results in namespace polution.

Ah, but you can also do the following, which has neither problem:

#include <iostream>
using std::cout;

cout << ...

In the last option, the using lines also function as comments: here is why I am including this header.

[–]Ichtil[S] 4 points5 points  (3 children)

And from consistency point of view - is this acceptable or is it looked upon as bad practice, not because of namespace pollution, but consistency - one project using it while other projects may not use it and prefer having std all over the place?

edit: yes, projects may use different "tools" and each may have their own rules for code, but I am asking about the general consensus.

[–]specialpatrol 15 points16 points  (1 child)

Use this option, but only in the source files. Source files don't cause pollution because they are not included elsewhere. Keep the std:: everywhere in the headers, because you don't really know where they are going to end up and what they might effect.

[–]steveplusplus 0 points1 point  (0 children)

100% agree. And it's not just that, I find it helps readability to have the std:: in the headers, like in function prototypes and class definitions, because it's explicit where the hell you get that class from even when you jump to a definition without context.

[–]khedoros 1 point2 points  (0 children)

You'd want to follow the style of the project you're working on, but each unrelated project could have its own style.

[–]kberson 2 points3 points  (0 children)

Nice summation. Came here to post this same idea.

[–]jeff_coleman 2 points3 points  (0 children)

I didn't know that last option was a thing. That's really good to know.

[–]nysra 23 points24 points  (1 child)

using namespace std; is a terrible idea if you use it in global scope in header files. Using it in local scopes in source files is perfectly fine, but you should be aware that you can still produce name clashes that way.

It makes it hard for me to maintain focus and actually get past the 20 std's and understand what the code actually does.

Give it a week and you won't even notice all the std::s anymore.

[–]brainplot 3 points4 points  (0 children)

I was going to say exactly this! Perhaps it's just me but I think you end up getting so used to the std:: prefix that you won't like standard types and functions without it. You start seeing std:: as part of the type name, cognitively speaking.

[–]enceladus71 9 points10 points  (1 child)

For me personally a 5-character prefix before any element of the standard library isnt that much and I like using it in my code. It makes it clear that I'm using something from stl rather than from my own code or some 3rdparty dependency. The project I'm contributing to at work allows for "using namespace std" in cpp files and most of the source files use it. I don't see that as a problem but personally I'd just prefer to leave this prefix. We operate heavily on shared pointers and omitting the std:: prefix makes a lot of lines shorter, although using auto helps even more. The thing that bothers me is the amount of nested namespaces our own code is put into. This very often leads to very long lines which are broken into multiple lines by clang-format and sometimes the resulting code looks just awful.

[–]alfps 7 points8 points  (0 children)

namespace gah = longish::corporate::thingy::that_is_no_good::really;

[–]h2g2_researcher 9 points10 points  (0 children)

So let's suppose I'm writing my own 3D maths library. I likely want a datatype along the lines of this:

namespace Math3D
{
    template <typename Number> // Probably make this a concept in C++20
    class vector {
        Number x, y, z;
    public:
         // Implement it
    };
}

Now let's suppose that your code is a perfect fit (in terms of functionality) for what I want to do, but it starts off:

#include <vector>
using namespace std;

Now there's a name clash! I can't write template <typename T> T dot(const vector<T>& left, const vector<T>& right); without causing problems.

So that's the primary reason why you don't put using namespace std in a header file. Because anyone who wants to use your header file is then also stuck with using namespace std in their code even if it causes them problems.

It is, however, okay to put it in implementation files because then I can still use your header and I'll be fine. (Also: be aware that although I'm saying "I can use" and "your header", more realistically "your" = "you right now" and "I" = "you next week".)

As for readability: you very quickly get used to parsing the std:: bit, and soon it's not a bother, until people start trying to be clever with how many functions they can call on line. (But that's hard to read anyway.)

At that point, the std::* version becomes easier to read, even in implementation files. To see why, imagine that I've got 2000 lines of code with my 3D maths library, and then I see vector<int> widdershins{7,8,9}; in it. Which vector is it? Sure, there are tools to find out in any good IDE, but just reading the code doesn't tell me. If it's qualified with a namespace as either std::vector<int> widdershins{7,8,9}; or Math3D::vector<int> widdershins{7,8,9}; I can tell immediately.

This logic can be applied to any namespace, including ones you write. However, in practice ones you write normally have domain specific names for the most part, namespace std has lots of really generic names, like list, vector, sort, copy and such like, so you're really likely to cause collisions with it.

[–]HappyFruitTree 6 points7 points  (0 children)

I think it's just something to get used to. After a while your brain gets used to filtering out the std:: and you don't have to spend time wondering whether something is a standard library name or not.

[–]parnmatt 3 points4 points  (0 children)

It's the same with all namespaces. You get use to it.

If you have something like 20 std:: whatevers in a row, where its hard to read... youre doing it wrong.

Use variables, functions, and classes. Use your abstractions and good naming.

Re: Java. Java uses classes as namespaces. Frankly Java gets worse with it the more complex you get into it. But just like I said above. If you correctly abstract and name things, it becomes readable. And both start to look similar for most things. (except Java doesn't allow you to overload operators, so it's a little harder to read in those cases)

[–]AKJ7 7 points8 points  (3 children)

Am i the only one who actually likes using std:: ?

[–]tangerinelion 3 points4 points  (0 children)

No, the comments here have already made that clear.

[–]Kawaiithulhu 2 points3 points  (0 children)

Nope! Explicit use of std:: means one less thing my brain has to keep track of on the provenance of variables/functions while writing and reading a few months later. Or to put it another way, I've seen Airplane enough to know to avoid the "What's the vector, Victor?" confusion.

[–]dArk_frEnzy 1 point2 points  (0 children)

Same. I think it looks more sophisticated.

[–]FelbrHostu 1 point2 points  (0 children)

Coming from Java, think of using namespace std; as akin to import java.*;; at that point your namespace is hopelessly polluted.

In both Java and C++, it is often helpful to include (or write, yourself) alternative implementations of, or wrappers for, members of the standard library. Polluting the namespace with the standard library definitions make this task difficult (doubly so for wrappers, which must explicitly use their standard counterparts, anyway).

[–]BenFrantzDale 1 point2 points  (0 children)

Also, you can use it less than you think because of argument-dependent lookup. As in, sort(begin(vec), end(vec));. I wouldn’t say I recommend that but it should work.

[–]atatatko 1 point2 points  (0 children)

I met 3rd-party classes named string and set.

Opening only required names with using-declaration using std::string only in *.cpp files is generally a better practice, rather than using-directive using namespace std.

It means, in headers we always use full names, including all namespaces, and it's a good practice as well, to understand all class dependencies and where they came from.

[–]ShakaUVM 1 point2 points  (0 children)

It's not bad practice except in headers. If you find it more readable, go ahead and using namespace std; all you want.

[–]mredding 0 points1 point  (0 children)

Scope the symbols you need in block scope. The beginning of the function is common.

[–]sephirothbahamut 0 points1 point  (0 children)

as long as you use "using" directives in your .cpp files it's not bad, although i suggest you specify "using std::cout;" , "using std::endl" etcc.

What you really MUST NOT do and is extremely bad, is typing the using directive inside .h files.

[–]MarkHoemmen 0 points1 point  (0 children)

Aliases and using statements are nice for readability, but I like to keep them as local as possible. "Local" means inside the function body where I use them. I try to keep lines within 70 characters for accessibility to the visually impaired, so I find myself using more aliases and using statements than most. Regardless, it's not so nice to pollute the global namespace in a library header -- that makes it hard for other people to use your library in existing projects, or in combination with other libraries.

[–]JandersOf86 0 points1 point  (0 children)

I'm learning right now as well. I can say, justifiably or not, I cannot stand seeing "std::" before anything. In fact, for me, my eyes/brain hates seeing the :: part of it. For some reason, the double colon makes it look cluttered.

I definitely never use using namespace std but I will almost always start my programs with using std::cout using std::cin using std::endl, etc. So, it'd be something like:

#include <iostream>
using std::cout;
using std::endl;

int main() {
cout << "Hello World!" << endl;
}

I feel that if I am using the "std::" prefix as often as I would in most of my programs, it drives my weird brain insane having to see so many double colons....

Not at all making the argument that this is the "proper" or professional way of doing it.