I don't know about community consensus but I've come to favor not only using declarations but using directives (ex: using namespace std;
) in source files (not for headers, of course, at namespace scope). At least Sutter seems to share the same wavelength. From his 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. -- Herb Sutter
I didn't always favor using directives let alone declarations. When I started using C++ some 25 years back or so, I favored the more verbose and explicit style since my rationale was that I could use the exact same style in headers and source files. However, the main reason I wanted to pitch in was to share some experience dealing with real bugs in production code that came from failing to use the proper namespace(s). I've encountered at least a good dozen or two in my career, and some were very painful.
I've forgotten most of the precise details of each one, but they all had to do with using the wrong overload of a function or operator (ex: a generic version) from the wrong namespace combined with argument-dependent lookup which satisfied the compiler but produced the wrong runtime behavior. These were all in massive codebases spanning millions of LOC. All of them could have been easily avoided with using directives, and it was after encountering the first few of such bugs that I began favoring and even promoting using directives for source files.
The one I remember very clearly but was actually the most trivial to detect and fix was a case where I found some code where a third-party dev whose source we acquired had included <cmath>
, but used the wrong version of abs
. The dev forgot to put std::
in front and passed in a floating-point parameter, only to get back an integer result cast back to floating-point from the version of abs
that C defines in the global namespace. That was one of the simpler cases and I ended up debugging his code and fortunately found it quickly by looking at the compiler warnings, but it's yet another example of how omitting using directives and declarations in source files can lead to actual runtime bugs and grief for our customers.
Meanwhile, I've been using C++ for such a long time, and have worked in the widest variety of codebases ranging from the foulest with shoddy standards and testing procedure to reasonable ones, and there was only one time where I encountered a clash resulting from using directives. Just one for people concerned about using directives/declarations possibly resulting in clashes. It was one time in the 90s when we ported our product to CodeWarrior for the Mac, and CodeWarrior had some standard header which defined an identifier like Polygon
in the global namespace which clashed with one we used from our own namespace. Took like 15 minutes to fix and was a simple compiler error, not a runtime bug. So from my standpoint, using
directives and declarations in source files can actually prevent human mistakes from turning into bugs, while any rare clash that might result from that is most likely just going to result in a simple compile-time error.
std::
everywhere seems cluttering the code a lot".