I was looking at the google coding guide [here] and they do not recommend that one use the using namespace
or namespace::function
- if I did not misinterpret it.
Does this apply to std
as well? cout<<
does not work without it. This book, recommends the same. So how do I go about using cout<<
without using namespace std;
or std::cout<<
?
What is the recommended way? std::cout<<
? Most c++ text books teach beginners with using namespace std;
are they propagating poor coding practice?
6 Answers 6
As I read the Google standard, you cannot use the using namespace foo;
directive anywhere. This directive brings in everything declared in the namespace and is a common cause of collisions and unexpected behavior. Others have cited a very common one: you have your own max or min method somewhere and it collides in a src file where someone includes a header with your method and then says using namespace std;
In certain places, it is permitted to have a using declaration, which is of the form using ::foo::bar;
People like to put using directives in their code because it saves a lot of typing, but it comes with risk. If you have a file with a lot of cout statements, I can understand not wanting to have to type std::cout a hundred times, but you can simply say using ::std::cout. I treat these like variable declarations: scope them where they are needed. If one function in a file of 10 needs to write output, don't declare the cout way at the top, put it in that function that is doing the actual output.
#include <ostream>
//using namespace std; // NO!
//using ::std::cout; // less bad than using namespace, but I prefer to scope it
int main(int argc, char** argv)
{
int rc = do_some_stuff(argc, argv);
using ::std::endl;
if (rc) { // print the success report
using ::std::cout;
cout << "The test run completed. The return code was " << rc << '.' << endl;
} else {
using ::std::cerr;
cerr << "Unable to complete the test run." << endl;
}
return 0 == rc;
}
That's a little extreme with just a couple of lines doing output, but you get the idea.
Another thing one can do is alias or typedef to minimize the typing. I don't find std::whatever to be that bad, but we have a huge set of source with several dozen modules and sometimes we have to write code like console_gui::command_window::append("text")
. That gets tedious after a while and causes a lot of long lines. I am all for something like
typedef console_gui::command_window cw;
cw::append("text");
as long as the aliases are done in a local scope and keep enough context to make the code readable.
-
1Thanks! This is really helpful. You not only explained why it is bad with nice examples, but also pointed out solutions with nice examples. :-)Lord Loh.– Lord Loh.2014年04月25日 23:57:25 +00:00Commented Apr 25, 2014 at 23:57
-
1BTW: Using
std::endl
for the explicit flush onstdout
/stderr
is normally quite superfluous, those streams are tied tostdout
/stderr
anyway. It even slows things down a bit.Deduplicator– Deduplicator2014年11月21日 13:14:10 +00:00Commented Nov 21, 2014 at 13:14
This is because: 1) it defeats the entire purpose of namespaces, which is to reduce name collision; 2) it makes available to the global namespace the entire namespace specified with the using directive.
For example, if you include and define your own max() function, it will collide with std::max().
http://en.cppreference.com/w/cpp/algorithm/max
The preference is to use std::member_you_wish_to_use because it explicitly states which namespace to use.
-
I presume this means I should use
std::max()
with the name space prefix. Or am I mistaken?Lord Loh.– Lord Loh.2014年04月19日 22:45:52 +00:00Commented Apr 19, 2014 at 22:45 -
3It means that if you put "using namespace std;" in your code, you will get errors if you define your own max function (or any other name already defined in the std namespace)Chewy Gumball– Chewy Gumball2014年04月19日 23:16:21 +00:00Commented Apr 19, 2014 at 23:16
-
1It just means that you should be careful with
using
directives because in this case it would break your max() function if you had defined one and included <algorithm>. This is a simple case but you never know what you might break. You'd need to know the entire library to be sure you didn't break it but you can't know if your code would break (i.e. name collision) in the future.ApplePie– ApplePie2014年04月20日 00:41:59 +00:00Commented Apr 20, 2014 at 0:41
Quoting the link you provide:
You may use a using-declaration anywhere in a .cc file, and in functions, methods or classes in .h files.
// OK in .cc files.
// Must be in a function, method or class in .h files.
using ::foo::bar;
Google style forbids you using importing namespaces in global context, but allows to do so in local ones.
Everywhere where using declaration only affects a limited and clearly visible portion of code it is perfectly acceptable.
When you pollute global context, unrelated code is affected (by implicilty using your header). Nothing happens when you do so in local context.
-
We have the same standards. Some of our people will locally typedef a long namespace. e.g. typedef foolicious::barlicious fb; fb::drink d;Michael Mathews– Michael Mathews2014年04月24日 21:37:48 +00:00Commented Apr 24, 2014 at 21:37
Here you go:
#include <iostream>
int main()
{
std::endl(std::operator<<(std::cout, "Hello world!"));
}
By writing it this way, we avoid error-prone ADL along with using directives and declarations.
This is meant to be a sarcastic answer. :-D
I'm with Herb Sutter over Google on this one. From C++ Coding Standards:
You can and should use namespace using declarations and directives liberally in your implementation files after #include directives and feel good about it. Despite repeated assertions to the contrary, namespace using declarations and directives are not evil and they do not defeat the purpose of namespaces. Rather, they are what make namespaces usable.
You can obsess about potential namespace conflicts that will probably never manifest and probably won't be difficult to fix in such an astronomically rare event by carefully avoiding using
directives and explicitly specifying each and every thing you use (down to the operators) with using
declarations, or just go ahead and start using namespace std
. I recommend the latter from a productivity standpoint.
Most c++ text books teach beginners with using namespace std; are they propagating poor coding practice?
The opposite if you ask me, and I believe Sutter above agrees.
Now, over the course of my career, I have encountered around 3 namespace conflicts total as a direct result of using
directives in codebases spanning tens of millions of LOC. However, in all 3 cases, they were in source files that spanned over 50,000 lines of legacy code, originally written in C and then bastardized to C++, performing a massive eclectic list of disparate functions, including headers from a dozen different libraries, and having an epic list of #includes
that spanned over a page. In spite of the epic mess, they weren't too difficult to fix since they caused build errors on OSX (the one OS where the code failed to build), not runtime bugs. Don't organize your code this nightmarish way and you should be fine.
That said, avoid both using
directives and declarations in header files. That's just plain retarded. But for source files, and especially ones that don't have a whole page filled with #include
directives, I'd say don't sweat it if you aren't working for Google.
they do not recommend that one use the using namespace ornamespace:function` - if I did not misinterpret it.
You did. The disrecommendation only applies to the using namespace
directive (which is commonly referred to as abusing namespace
, not entirely humorously). It is strongly preferred that you use the fully qualified name of a function or object, such as std::cout
.
Although the question has already useful answers, one detail seems to fall too short.
Most programmers are at first a bit confused with the using
keyword and the descriptions of namespace
usage, even if they try to learn it by looking up the reference, because declaration and directive reads somewhat equivalent, both are relatively abstract long words starting with d.
Identifiers within namespaces are accessible by explicitly naming the namespace:
myNamespace::myIdent
this may be a lot more keys to type. But it may also decrease the significance of your code, if most identifiers get prefixed the same way. The using
keyword helps to prevent these namespace downsides. Since using
works on the compiler level (it's no macro), its effect lasts for the whole scope it is used in. That's why Google style restricts its usage to well defined scopes, i.e. classes in header files or functions in cpp files.
...of course there is a difference between using declaration
using myNamespace::myIdent; // make myIdent an alias of myNamespace::myIdent
and using directive
using myNamespace; // make all identifiers of myNamespace directly accessible
If used in huge scopes, the latter leads to much more confusion.