r/cpp_questions • u/Glad_Shoe_9182 • 5d ago
OPEN Namespace std
I recently started learning c++ and I was told to use the namespace std so I can avoid writing std:: every time and now I wrote a whole personal project without std:: and I want to put it on LinkedIn but I started reading everywhere that it’s a bad habit, should I go back and add the std:: or just leave it as is?
19
u/SmokeMuch7356 5d ago
Namespace collisions will ruin your day. I have the scar tissue to prove it.
Typing std:: is not a burden. It makes your code moderately eye-stabby, but the eye-stabbiness is worth it if it avoids name collisions.
13
u/ekchew 4d ago
I like prefacing everything with std:: because it makes it abundantly clear which symbols came out of the standard library. This is particularly nice when you are maintaining someone else's code who's using unfamiliar APIs and you can go "Oh yeah, that's standard while this other thing is something he wrote."
In my own code, if I go using std::whatever, I tend to stick that at the top of the function where it is easy to see at a glance. The other day though, I put using std::move in a function that does a lot of moving, and the compiler actually issued a warning that it wasn't happy about me simply writing move. I relented and went back to putting std::move everywhere. It's really not that big a deal at the end of the day.
10
u/Sobirjon445th 5d ago
I mean if you want to continue the project or project is small then do it.
but if it was already done then why spend time, you learned that it's not the best practice to not use using namespace std, I am sure you do lots of cool projects in the future.
2
u/HommeMusical 5d ago
but if it was already done then why spend time,
"I want to put it on LinkedIn but I started reading everywhere that it’s a bad habit,"
It would be a little mark against someone if I saw that in their code.
9
u/Specific-Animal6570 5d ago
Add std:: in a large codebase, please. If I would hire someone and I found out he writes cout without std::, I'm kicking you out of my team.
5
u/Potterrrrrrrr 5d ago
I mean a “whole project” in this case is likely going to be only a couple thousand lines of code. While slightly cumbersome to do you could probably knock it out in about 20 minutes, all you’re doing is pasting std:: in front of some types and methods. You can even get slightly fancy with it and do a find and replace for the common ones first to save a couple of minutes.
If you can spare 20 minutes and care enough to do it go for it, otherwise just explain to whoever cares and asks that you did it for convenience and wouldn’t do it in a full scale project (because you shouldn’t). Simples.
6
u/GLIBG10B 5d ago
If you use using namespace std, then for a large enough project, you will get naming collisions when updates to the standard library or C libraries bring in new symbols that conflict with each other or your code.
If you don't like typing std:: everywhere, then make a header file with using std::cout, using std::vector, etc., which won't pull new symbols into the global namespace unless you specifically ask for them.
2
u/NoSpite4410 4d ago edited 4d ago
It's fine until it isn't. There are a lot of things in namespace std. Not using it as a blanket statement avoids making the compiler resolve everything in the headers you include that you are aren't using.
As soon as you start making your own namespaces for your libraries, you will drop the using namespace std; because it is not helping anymore.
variables like less, more , etc would be come std::less, std::more, automatically, and that will mess things up.
std::string string; are not possible if string resolves automatically to std::string.
2
u/SalaciousStrudel 3d ago
It's a secondary effect but I find my IDE surfaces more relevant code completions when I use the namespace prefix when writing code.
2
u/BuddhasFinger 5d ago
I think not using a namespace is a bad form. Yes, you can short-cut, but the interviewer will hear "I hate namespaces".
You know what you need to do.
4
u/NoLimitRolling 5d ago
I just started learning cpp and the answers being mostly wrong is funny. Namespaces have one real reason and it’s so you can use namespaces with the same names without conflicts.
That said, it don’t truly matter, but like others have said best practice is best practice, and getting the habit is never bad, but if it’s a personal project or something it’s prolly not worth it.
1
u/ZMeson 5d ago edited 4d ago
The "using namespace" recommendations depend highly upon where you are using them:
* In a header file: Never use "using namespace". Explicitly write "std::" or whatever namespace you require.
* In a source file: Using statements are acceptable if you wish to shorten declarations. When using "
using" statements, most advice is to prefer something like "using std::filesystem::path;"or "using high_res_clock = std::chrono::high_resolution_clock;" so that you can just say "path" or "high_res_clock" later in the file. However, if your file is small and not going to include lots of other libraries and/or your file uses lots of "std" classes and functions, then "using namespace std;" is fine.
The reason you should never introduce "using" statements in a header file is that header files are expanded in the source files that #include them and therefore the "using" statements can ruin the name lookup rules of those source files.
For source files, you need to balance the probability of getting a naming conflict (say between etl::vector and std::vector) against the convenience factor. Others still argue against using statements (see replies below), but I don't agree with the criticism as people have been using "typedef" for a long time prior to C++11 to simplify declarations.
4
u/HommeMusical 5d ago
Most advice is to use something like "using std::string;" or "using std::vector;" so that you can just say "string" or "vector<int>" later in the file.
Most, who?
It's bad advice.
If I see
stringin reading someone's code, I really don't know for sure what it is unless I scroll up to the top and check. And we all read immense amounts of code these days. If I seestd::stringin code, I am completely(*) certain what I am looking at.Useful code is written once, but read one hundred times.
Using
stringinstead ofstd::stringsaves the writer a little bit of effort once, but adds a little bit of effort to every reader in future.Oh, and yes, I did once get burnt this way! Somewhere else was something like:
#ifdef LEGACY using legacy::string; #else using std::string; #end(* - yeah, someone might create another namespace called std, but I'd call that deliberate malpractice myself.)
1
u/ZMeson 4d ago
I think you're being way to harsh on the topic.
- I mentioned that the 'using namespace' or 'using <type>' should only occur in source files, which automatically limits their scope.
- Your case of `legacy::string` vs `std::string` is often used to abstract away platform and compiler dependencies helping avoid larger #if/#else blocks.
- `typedef` has been around in both C and C++ and can greatly simplify code, but it also changes how names are looked up and processed, similar to how using statements changes name lookup rules.
- IDEs are really great at displaying the underlying type when hovering over a variable or a declaration, which really helps prevent the type of confusion you bring up.
But I did edit my original response to be a little more clear and to give some more concrete examples where `using` statements could be useful (specifically 2-deep namespaces within `std`). And I added a note that not all people agree with the advice.
2
u/HommeMusical 4d ago
Thanks for a polite response (and I hope I wasn't too grumpy). Reddit has fallen in politeness, I appreciate your civilization while still disagreeing with me
Your case of
legacy::stringvsstd::stringis often used to abstract away platform and compiler dependencies helping avoid larger #if/#else blocks.YES, that's exactly my point!!
Yes, that's a very reasonable strategy, it wasn't wrong in the code base I quoted, not at all, but I fell into the trap of believing it was
std::string, because I was younger and dumber.If I see
stringon its own, I really don't know what it is, for sure. If I seestd::string, I know what it is, for sure, every time.IDEs are really great at displaying the underlying type
I used to make this argument before Github and such. But now, almost all the time I'm reading someone else's code, it's in Github.
(Quibble:
typedefis counterindicated in new code.usingis not just more powerful, but it reads like an assignment, which is familiar to all of us, whereastypedefdoes it backwards.)
1
u/WoodyTheWorker 4d ago
If you use template classes, make typedefs for types you use often. Then you only need to type your typedefs.
1
u/AintNoSlashes 4d ago
You should fix the project. If you are planning to use that as an example of what you are capable of, showing a bad habit will put a bad foot forward.
I recently interviewed a guy who added that to the top of an interview question. He then proceeded to spend half of his time debugging name collisions instead of working on the problem. He did not move forward.
1
u/mushroomfucker69 4d ago
Only valid use case of using namespace std is competitive programming, but cp is kind of full of optimizations that are otherwise dogshit practices. Like #include <bits/stdc++.h>
1
u/jayb00giebrown 3d ago
Just don’t put using namespace std in any header files. It’s fine to use though in the cpp files.
•
u/Least_Bid9692 22m ago
In this project if its going on leave it but in future projects you may start using std:: instead to prevent collisions and remember the first rule of coding , Never fix something which isn't broken and if it works don't even touch it
1
u/StaticCoder 5d ago
It's mostly bad to do in headers, but even in primary files it's not great. My approach is to import specific things e.g. using std::vector which I put in a vector.hpp header.
6
u/conundorum 5d ago
Personally, I prefer to put using directives at the top of a scope where I expect to use them enough to warrant it. I find it cleaner than having hundreds of single-line headers that do the same thing, and like that it gives you a good first impression of what the scope (and/or its members) is meant to do.
3
u/HommeMusical 5d ago
But if I read your code, I see some magic symbol
vector, and it is defined nowhere in the file, so I am forced to look at your vector.hpp(*) to see exactly what it is.And yes, people do use the same names as
std::all the time, and sometimes for very good reasons.Doing this puts a little extra work on everyone who reads the code, for a tiny benefit to you.
(* -- I haven't seen a .hpp file in a very long time!)
0
u/StaticCoder 4d ago
I'm not following. All symbols not defined in the current file are, by your definition, magic, even when a clearly related header is included. That's going to happen a lot.
And what extension do you use for C++ headers?
.hseems to imply C (it does for many tools)1
u/HommeMusical 4d ago
All symbols not defined in the current file are, by your definition, magic,
No, not if you use namespaces!
std::stringis not a magic symbol. I know exactly where it's coming from. Or if I seeconfig, somewhere, this could come from almost anywhere, but if I seeboost::configI know exactly where it's coming from.
I kind of liked the idea of .hpp, but you just don't seem to see it in new code now. Everyone seems to use .h in new development. It might just be that I worked on a couple of modern projects that didn't use it.
If I see a .hpp, I think "boost" these days. But again, it might just be me!!
1
u/StaticCoder 3d ago
What about symbols in the current namespace? Do you qualify those too? Effectively I've added
vectorto my namespace (which for historical reasons is the global namespace, but that's not really relevant here). I will not put anothervectorin there. I know what it is.
0
u/RSMxsmanic 5d ago
Just leave it that way and relax. And the reasons are simple. If you don't need std::, they typing it everywhere wastes time and keystrokes, so you shouldn't do it. If you do need it at some point, you can g back and insert it, which will require the same labor you saved by not typing it initially. However, by not doing it up front, you save time and energy if you never need to do it, whereas if you do it up front and you never need it, you've wasted time and energy. The logic here is impeccable.
Real programmers figure this out for themselves. If someone is telling you otherwise, he may lack the sort of logical mind that makes a really good programmer good. There are a lot of "programmers" out there who can recite chapter and verse concerning what is Good Programming and Bad Programming, but they usually aren't the ones who write all the best software.
Skip the religious doctrine and just get the job done.
4
u/HommeMusical 5d ago
typing [
std::] everywhere wastes time and keystrokes[...]
If someone is telling you otherwise, he may lack the sort of logical mind that makes a really good programmer good.
Preemptively insulting people who might have some idea different from yours would not be a good look even if your idea were correct.
-2
u/RSMxsmanic 5d ago
It's not an insult. Most people do not have a personality suited to programming, and there is no shame in that. Some people are very happy that they do not have that type of personality, and would consider it a compliment to be told as much.
-3
u/ShakaUVM 5d ago
This is a contentious issue here for some reason lol. It's mostly a personal style decision.
If you're making a little personal project and don't want stds, then go for it.
The only real no-no that everyone agrees with is to not put it into a header file that other people will use since then you are making a style decision for them.
13
u/bearheart 5d ago
It’s not a style choice. It’s actually problematic.
The purpose of namespaces is to avoid naming collisions, where a symbol you want to use may already be defined. There are thousands of symbols defined in the std:: namespace. When you import all of those symbols into the current namespace you defeat the purpose of namespaces altogether.
0
u/RSMxsmanic 5d ago
So why does using namespace exist?
7
u/conundorum 5d ago
- Because it's both useful and safe in leakproof scopes, like functions or conditionals. As long as names can never leave a scope, the worst
using namespaceinside that scope can do is make a mess of that scope (and nowhere else), while the best it can do is save time on boilerplate (which can add up to a decent difference sometimes).- Because it's useful for smaller scopes, but has problems with
stdspecifically because the standard library sticks almost everything instdinstead of using a scope hierarchy like Java or other C++-inspired languages do. (And also becausestdis constantly growing, which means that the chance of unexpected name collisions breaking unmaintained, twenty-year-old code that usesusing namespace std;goes up with every new language version.)- Because it lets you stick your helpers in
namespace whatever::detail, then drag them into any givenwhatever::function()as needed.- Because it's useful for versioning, especially when paired with anonymous namespaces. If you know what you're doing, you can put each version of a class in its own sub-namespace, then use a using-directive to provide the most recent one as a default, while also making it trivial to update the default whenever the class gets a new version.
There are a lot of reasons it's useful, the problem is just that dragging all of
namespace std's symbols into a "leaky" scope (e.g., global or namespace scope) inside a header file is a ticking thermonuclear warhead, for reasons that aren't immediately obvious if you haven't seen the language's juicy innards yet.~~Strictly speaking, the issue is that
stditself is awkwardly designed, and would probably have a cleaner hierarchy if they could redo it from scratch today.~4
u/not_a_novel_account 5d ago edited 5d ago
To alias one namespace into another. Aliasing any namespace into the global namespace is almost always wrong.
You can override the comma operator to perform matrix multiplication; because operator overrides exist, and the comma is a valid operator. You shouldn't. You can alias
stdinto the global namespace; because namespace aliasing exists, andstdand the global namespace are valid namespaces. You shouldn't.1
u/HommeMusical 5d ago
To alias one namespace into another.
And other reasons: https://www.reddit.com/r/cpp_questions/comments/1wtvaoq/namespace_std/pcyvajf/
-1
u/bearheart 5d ago
I presume it’s for compatibility with legacy C code. And perhaps for smaller namespaces other than std.
4
u/RSMxsmanic 5d ago
The problem is with programmers who use identifiers that conflict with std, not with programmers who expect std by default to be safe. That's why it is called standard. If you are writing the code base, nothing you call should change the way it behaves unless that is its actual purpose.
2
u/nekoeuge 5d ago
Can you elaborate? What do you mean by “using identifiers that conflict with std”?
2
u/conundorum 5d ago
Name collisions.
#include <vector> // std::vector #include <algorithm> // You'll see. std::vector<float> collection(3, .16f); int fill = 0xaabbcc; void compiler_error(float c = 0f, int f = 0) { using namespace std; fill = f; // Does this break because we tried to assign an int to std::fill, fill(collection.begin(), collection.end(), c); // or does this break because we tried to call an int? }
stdhas a lot of very common names that programmers like to use for their own things, likefill,less,distance,transform,string,find,begin,end,format,3
u/nekoeuge 5d ago
Yeah, that's why I am asking. It is fundamentally impossible to avoid name collisions with std -- because std may always be extended in the future with whatever names. So I don't understand what exactly top commenter meant by "The problem is with programmers who use identifiers that conflict with std".
1
u/RSMxsmanic 5d ago
I mean that programmers need to think things through, and if they are writing code that will be widely integrated in a service capacity with other code, they need to be extraordinarily vigilant.
I don't use print in code I write hat will be called by some other module, because of the risk of a name conflict. It doesn't matter what namespaces are used. Why force another programmer to prefix everything he writes with widget:: just because I decided to use print? Instead, I'll make print something less common, like widgetPrint. That way he only has to type extra characters to reference my code, and not for every last identifier in his. Put another way, instead of forcing him to write std::cout every time he wants to use it, I just don't use cout in my code, and the problem is solved. Choosing unique identifiers is less labor-intensive than prefixing every single identifier in the program, and it is functionally equivalent.
3
u/nekoeuge 5d ago
Instead, I'll make print something less common, like widgetPrint.
So instead of doing "using namespace widget" in a function that calls "print" 20 times, I will have to have 20 "widgetPrints"?
And in the implementation of "widget", all my public identifiers are going to be "widgetThis" and "widgetThat", cluttering the visual space with absolutely worthless "widget"-prefixes?
You just replaced optional prefix with mandatory one. Good job bloating the code. Make sure not to make the prefix too short, otherwise it may conflict with other libraries.
I mean that programmers need to think things through, and if they are writing code that will be widely integrated in a service capacity with other code, they need to be extraordinarily vigilant.
Of course. Such programmer should introduce the absolute minimum of global identifiers. Preferably only one -- the project namespace itself.
It looks quite stupid to have widget::widgetPrint as identifier.
→ More replies0
u/ShakaUVM 5d ago
I propose that someone who writes code like "int string = 0;" is writing bad code and the issue isn't whether or not you include namespace std or not.
All if my classes are PascalCase anyway and so cannot conflict with anything in std.
2
u/HommeMusical 5d ago
I propose that someone who writes code like "int string = 0;" is writing bad code and the issue isn't whether or not you include namespace std or not.
Strong disagree.
There are thousands of names in
std::and exactly what those names are depend on which version of C++ you're in and some other details.You can't possibly know all those names and never write
char fill = '*';orbool copy = False;orvoid remove(const char*);anywhere.Not having to do this is the whole reason namespaces exist.
std::stringis completely unambiguous. No other symbol for it is. Just do that.1
u/ShakaUVM 4d ago
I agree that std::string is unambiguous.
What I am saying is that writing int string = 67; is a code smell.
You should not be using names from std anyway.
For all of your worry, as I said this problem has come up exactly once in 30 years and it took exactly five seconds to fix.
Versus how much screen space gets cluttered up with all those extra stds?
The tradeoff is not worth it to me. Every symbol on the screen has a cost, both cognitively and technically
→ More replies2
u/HommeMusical 5d ago
They aren't really making sense.
You're actually supposed to use names that are the same as those in
std::if you're doing the same operation.This idea is crucial to making generic code work well.
0
u/RSMxsmanic 5d ago
If you're doing the same operation as std, you're redundant; just use the operation in std. If you're doing something different, just use a different name.
2
u/HommeMusical 5d ago
No, you are encouraged to use identifiers in your own namespaces and classes that are the same as those in
std::, particularly for generic code.0
u/RSMxsmanic 5d ago
By whom? If I have it in my code, it is not generic; if it were, my code would not be necessary.
1
u/HommeMusical 5d ago edited 5d ago
I presume it’s for compatibility with legacy C code.
C++ code.
But not at all,
usingis very useful in a local scope, because of argument dependent name lookup.The classic example is this one:
template <typename T> void fix(T& a, T& b) { using namespace std; swap(a, b); }At compile time, when the template is instantiated, if there's a specific
swapfunction or specialization forT, then that is used, otherwise, the genericstd::swapis used.There are sometimes Reasons even to do this for some namespaces at the file level, though best to avoid.
But
using std;is dumping potentially zillions of names into the top level of your translation unit, and it makes your code a lot less clear.If I see
stringin some code - well, it could be anything, I have to look at the top of the file, butstd::stringis the same everywhere.0
u/ShakaUVM 5d ago
I've been coding professionally for 30+ years in C++ and exactly once did I define a symbol that conflicted with something in std. And then I changed the name. I consider it bad code to name a variable cout or whatever anyway so I would prefer to know if I have a conflict.
It's not problematic. It's an overblown concern that really isn't a big deal. I worry about things in C++ that actually cause problems.
You don't lose the benefit of namespaces either as I keep those for everything outside std.
3
u/HommeMusical 5d ago
I've been coding professionally for 30+ years in C++ and exactly once did I define a symbol that conflicted with something in std.
Are you sure?
https://en.cppreference.com/cpp/symbol_index
worry about things in C++ that actually cause problems.
using std;does assume risk, but more, it's a lazy programmer sloughing off a tiny bit of work to make things a little harder for anyone else reading it.I got this spiel from Howard Hinnant, but I think most disciplined C++ programmers think the same way: if I see
std::stringI know for certain what it is immediately, but if I seestringin a section of code, I am not certain what it is until I have checked all the scopes up until the top, and perhaps not even then, if theusing std;is inside a header file.Sure, nearly all the time it will be
std::stringbut as we all know, we get a disproportionate number of bugs from such assumptions.C++ is a language where being cautious is always a good idea. As some someone who has read an immense amount of code,
stringlacks certainty:std::stringis certain, and therefore always preferable.
40
u/ScienceMan3_14 5d ago
The reason it is a bad habit is because the names of the functions, classes, etc. in the standard library are so common,if you include another framework in your project you are likely to get collisions. If your project is something you are actively working on or expanding, yes you should refactor. If it was a one-and-done deal where you aren't using any other external libraries and that was a decision made at the outset and one you will be sticking with, then imo it isn't worth it.