标签云

微信群

扫码加入我们

WeChat QR Code

I've been told by others that writing using namespace std; in code is wrong, and that I should use std::cout and std::cin directly instead.Why is using namespace std; considered a bad practice? Is it inefficient or does it risk declaring ambiguous variables (variables that share the same name as a function in std namespace)? Does it impact performance?


Don't forget you can do: "using std::cout;" which means you don't have to type std::cout, but don't bring in the entire std namespace at the same time.

2019年09月18日32分16秒

a paid nerd google-styleguide.googlecode.com/svn/trunk/… link does not work anymore. Looks like new link is google.github.io/styleguide/cppguide.html#Other_C++_Features

2019年09月18日32分16秒

It is particularly bad to use 'using namespace std' at file scope in header files. Using it in source files (*.cpp) at file scope after all includes is not quite as bad, as its effect is limited to a single translation unit. Even less problematic is using it inside functions or classes, because its effect is limited to the function or class scope.

2019年09月18日32分16秒

I would discourage to use using directive but for specific namespaces like std::literals::chrono_literals, Poco::Data:Keywords,Poco::Units and stuff that will deal with literals or readability tricks. Whenever it is in header or implementation files. It might be OK in a function scope I guess, but apart from literals and stuff, it is not useful.

2019年09月18日32分16秒

Jon: It's got nothing to do with namespace std in particular. My emphasis was meant to be on "at file scope in header files". To put it as an advice: Do not use "using namespace" (std or other) at file scope in header files. It is OK to use it in implementation files. Sorry for the ambiguity.

2019年09月18日32分16秒

I've always liked Python's "import big_honkin_name as bhn" so you can then just use "bhn.something" rather than "big_honkin_name.something"- really cuts down on the typing. Does C++ have something like that?

1970年01月01日00分03秒

Pax namespace io = boost::filesystem;

2019年09月18日32分16秒

I think it's overstating things to say it's "some effort to fix".You'll have no instances of the new foo::Quux so just disambiguate all your current uses with bar::Quux.

2019年09月18日32分16秒

Would any sensible person create a library with types whose unqualified name collide with the std types?

2019年09月18日32分16秒

TomA: The problem with #define is that it doesn't restrict itself to namespaces, but tramples over the whole code base. A namespace alias is what you want.

2019年09月18日32分16秒

It does significantly harm the density of code you can pack in a single line. You end up writing your code in a very long-winded way; which reduces readability. Personally, I think shorter (but not too short) code tends to be more readable (since there is less stuff to read, and less stuff to get distracted about).

2019年09月18日32分16秒

Guess you missed out on the old days before C++ had a standard string class, and seemingly every library had their own.Tell you what: We'll keep writing our code with std::, and you can run our code through grep -v std:: | vim when you're browsing it.Or you can teach your editor that std:: is a keyword which is to be colored the same as the background color.Whatever works.

2019年09月19日32分16秒

I don't think std:: is harmful at all. It carries very important information (namely "whatever comes after is part of the standard library", and it is still a pretty short and compact prefix. Most of the time, it's no problem at all. Sometimes, you have a few lines of code where you need to refer to specific symbols in the std namespace a lot, and then a using statement in that particular scope solves the problem nicely.But in the general case, it's not noise, it conveys valuable information in addition to removing ambiguities.

2019年09月18日32分16秒

Whenever I see std::, I know it's going to be from std:: without having to think about it. If I see string or list or map by themselves, I wonder a bit.

2019年09月18日32分16秒

LieRyan Then good luck writing a geometry library without ever naming something vector, transform or distance. And those are just examples of the many many very common names used in the standard library. Suggesting not to use them out of fear or a biased opinion of the namespace feature that is an integral part of C++ is rather counter-productive.

2019年09月19日32分16秒

This. Boost and std have a lot of overlap - especially since C++11.

2019年09月19日32分16秒

I did that once and learned a lesson the hard way. Now I never use using outside of a function definition and rarely use using namespace at all.

2019年09月18日32分16秒

Just one more programmer's opinion here, but while I agree 100% with the statement that the word using should never appear in a header, I'm not as convinced about the free license to place using namespace xyz; anywhere in your code, especially if xyz is std.I use the using std::vector; form, since that only pulls a single element from the namespace into pseudo-global scope, therefore leading to far less risk of a collision.

2019年09月19日32分16秒

Lightness Races in Orbityou are of course entitled to your opinion. Would have been more helpful if there had been some attempt at explanation why you do not agree with advice given in this answer. Especially would be interesting to understand what is the point of namespaces if 'using' them is bad? Why not just name things std_cout instead of std::cout ... the creators of C++/namespace must have had some idea when they bothered to create them.

2019年09月18日32分16秒

nyholku: No need - the majority of the other answers give the same reasons I would. Also please do no hesitate to note the ":)" I appended to my comment! And that I didn't say namespaces are bad.

2019年09月18日32分16秒

Yeah, I noticed that :) but IMO the majority of answer (that go against this sage advice) are misguided (not that I made any statistics what is the majority now). If you agree that namespace are 'not bad' then you might say where you think they are appropriate if you disagree with this answer?

2019年09月18日32分16秒

I'm sorry, but I strongly disagree with this.

1970年01月01日00分03秒

Billy: There is no other way to support calling userlib::cos(userlib::superint). Every feature has a use.

2019年09月18日32分16秒

Zan: Of course there is. using std::cos; , using std::sin, etc. The issue though is that any well designed userlib is going to have their sin and cos inside their own namespace as well, so this really doesn't help you. (Unless there's a using namespace userlib before this template and that's just as bad as using namespace std -- and the scope there is not limited.) Furthermore, the only function like this I ever see this happen to is swap, and in such cases I would recommend just creating a template specialization of std::swap and avoiding the whole problem.

2019年09月18日32分16秒

BillyONeal: template<typename T> void swap(MyContainer<T>&, MyContainer<T>&) (There's no function template partial specialization (FTPS), so sometimes you need to resort to overloading instead.

2019年09月18日32分16秒

BillyONeal: Your (7-times-upvoted!) comment is wrong -- the situation you describe is exactly what ADL was designed to cover.Briefly, if x has one or more "associated namespaces" (e.g. if it was defined in namespace userlib) then any function call that looks like cos(x) will additionally look in those namespaces -- without any using namespace userlib; beforehand being necessary.Zan Lynx is right (and C++ name lookup is byzantine...)

2019年09月18日32分16秒

"The implementation of std::swap was changed to find a potential overload and choose it." - What? Are you sure about that? Though it is true that providing a custom swap in the first place isn't that much important in C++11 anymore, since the std::swap itself is more flexible (uses move semantics). But std::swap automatically chosing your own custom swap, that is absolutely new to me (and I don't really believe it).

2019年09月18日32分16秒

ChristianRau I think so, yes. I read this on SO somewhere. We can always ask Howard, he should know. I am digging and digging now...

2019年09月18日32分16秒

Even in the swap case, the clearer (and thankfully more common) idiom is to write using std::swap; rather than using namespace std;.The more specific idiom has fewer side effects and therefore makes the code more maintainable.

2019年09月18日32分16秒

The final sentence is wrong. In C++11 the Std Swap Two Step was officially blessed as the right way to call swap, and various other places in the standard were changed to say they call swap like that (N.B. as stated above, using std::swap is the right way, not using namespace std). But std::swap itself was emphatically not changed to find some other swap and use it. If std::swap gets called, then std::swap gets used.

2019年09月18日32分16秒

It might be wiser to just type using std::swap locally though, to reduce the local namespace while at the same time creating self-documenting code. You are rarely ever interested in the whole std namespace, so just out pick out the parts you are interested in.

2019年09月18日32分16秒

+1 not to mention distance. still i prefer non-qualified names whereever practically possibility, since that increases readability for me. plus, i think the fact that we usually don't qualify things in oral speech, and are willing to spend time resolving possible ambiguities, means that it has value to be able to understand what one is talking about without qualifications, and applied to source code that means it's structured in such a way that it's clear what it's all about even without qualifications.

2019年09月18日32分16秒

To be fair, though, you don't have most of those if you don't include <iomanip>. Still, good point.

2019年09月18日32分16秒

Define "elegance".

2019年09月18日32分16秒

Is this a joke? I genuinely can not tell. If not then I personally would assume it's the normal 'cout' unless you don't trust the code since otherwise that would be a BEYOND MAJOR code smell, IMO. ... And if you don't trust the code then why are you using it in the first place? Note that I'm not saying "TRUST EvERYThING!!" but this also seems a bit far fetched if you're, say, dealing with some well known library from GitHub or something.

2019年09月19日32分16秒

BrentRittenhouse cout is a bad example because everyone recognizes it. But imagine future in a financial app. Is it a contract to buy or sell something at a specified date? No it isn't. If the code said std::future you would not be so easily confused.

2019年09月18日32分16秒

BrentRittenhouse maybe a little bad example, there are at least four different libraries that have cout. May be "is it standard library? libstdc++? stl? something else?" And no, not everyone knows std::cout, at least inherently, 6 of 7 new workers we receive don't. Because curricula of education doesn't use those in education. I have to chase away printfs. Or debugs() - from Qt.

2019年09月18日32分16秒

Really? It's pretty much in the first example of the first chapter of sooo many books on C++,if anything it (with insertion operator usage) is the only C++ some new bods know.

2019年09月18日32分16秒

mckenzm I might put it in a book or lecture notes to reduce clutter, but not in code

2019年09月18日32分16秒

That's a local using declaration, a very different thing from a using directive.

2019年09月19日32分16秒

How do you know "std::cout << 1" isn't reading a static int named cout in std namespace shifting it by one and throwing away result? Also how do you know what "<<" does ;) ??? ... seems like this answer is not good data point to avoid 'using'.

2019年09月18日32分16秒

If someone has redefined std::cout to be an integer, then your problem isn't technical, but social -- someone has it in for you.(and you should probably also check all of the headers for things like #define true false, etc)

2019年09月19日32分16秒

When I see cout I know it's std::cout, always. If I'm wrong, it's problem of person who wrote this code, not me :)

2019年09月18日32分16秒

Creating collisions isn't that hard - short strings like min, end and less appear in the std:: namespace. But more, now that std:: has thousands of symbols in it, it's useful for the reader to know where a new symbol they might not know comes from.

2019年09月18日32分16秒

The std namespace exists because people, either you, your colleagues, or people writing middleware you use, are not always wise about putting functions inside of namespaces.Thus you may import all of std:: and nothing else, while still invoking a collision between, say, std::min and someone else's legacy ::min() from before the time when it was in std.

2019年09月18日32分16秒

Just a minor comment, while typedef is useful I'd consider making a class that represents Lines instead of using typedef.

2019年09月19日32分16秒

Very interesting that a this answer that is based on guidance from no other that Bjarne Stroustrup has earned -2... boy Bjarne must have been a poor and inexperienced programmer when he introduced this feature into C++

2019年09月19日32分16秒

nyholku: See this.

2019年09月18日32分16秒

::count--problem solved. Usually you'll have more stuff from the std namespaced than from elsewhere, ergo keeping the using namespace directive might save you typing.

2019年09月18日32分16秒

The real problem here is that C++ still has namespace-less globals.This, and the fact that 'this' is implicit in methods, causes so many bugs and problems I can't even count them, even with the right 'count' variable. ;)

2019年09月18日32分16秒

It's not just 5 extra chars; its 5 extra chars every time you reference any object type in the standard library.Which, if you're using the standard library very much, will be often.So it's more realistically thousands of extra chars in a decent sized program.Presumably the 'using' directive was added to the language so that it could be used...

2019年09月18日32分16秒

Its not 5 extra chars every time, it is 5 chars and probably a couple mouse clicks to pull down a menu and do a Find and Replace in the editor of your choice.

2019年09月18日32分16秒

Readability. cout << hex << setw(4) << i << endl; is easier to read than std::cout << std::hex << std::setw(4) << i << std::endl;

2019年09月18日32分16秒

And even worse: std::map<std::string,std::pair<std::string,std::string>> is horrible compared to map<string,pair<string,string>>.

2019年09月18日32分16秒

It's a good practice is to typedef your STL containers anyway so std:: there really doesn't matter. And C++11 brought us the auto keyword which makes things even easier when e.g. using iterators.

2019年09月18日32分16秒

Extending the std namespace is undefined behaviour and thus should never be done.

2019年09月18日32分16秒

Given how many folk seem unaware of useful standard library functions (reinventing things from <algorithm>, for example), it seems a bit of a stretch to imagine that the same people could reliably avoid those identifiers.Look through your own code and tell me you never have a variable or function called count.Or distance, or log, destroy, launch, visit, beta, sample, messages, clamp, erase, copy, modulus, left, etc.Not to mention all the identifiers not yet in std that will break your code when C++35 comes out...

2019年09月18日32分16秒