3

I understand the rationale of avoiding using namespace std - this defines too many casual names the developer may not be even aware of.

I tried to work around the problem with the help of using construct. Most often, I it was using std::string and using std::vector, because these are really very common cases and writing std:: everywhere seems cluttering the code a lot. During the code review, it was pointed out that if I do this in the headers, the definitions propagate over many files without obvious consent, as the headers files tend to include one another. In response, I removed all using statements from the headers but moved them into .cpp files where the most of the code reside anyway. However during the next code review I was told to remove them from there as well.

I still have some doubts if using on the top of the cpp file that is never included into another file still may have big negative consequences. It seems to me that having no namespace prefixes for very common case like string or vector makes the code easier to read.

I would like to clarify, if the current major consensus in C++ community really discourages putting some common names (using std::vector and using std::string) of the std:: namespace on the top of the .cpp (not header) file. If this is really the case, it would be good to know why.

6
  • 4
    Your peers clearly don't agree with your statement "writing std:: everywhere seems cluttering the code a lot".
    – Caleth
    Commented Feb 27, 2020 at 13:42
  • I agree may be different philosophies. Python developers are very much into that any more verbosity just kills the productivity outright, I understand this is another language.
    – h22
    Commented Feb 27, 2020 at 14:46
  • 2
    The only thing that matters here is what is going to pass your code review. Ask the folks reviewing your code what the best approach is. Commented Feb 27, 2020 at 14:48
  • 1
    And perhaps ask the reviewers why they don't like seeing "using" in a .cpp file.
    – Simon B
    Commented Feb 27, 2020 at 15:39
  • I would like to see the answer as it sounds from the view point of the software engineering. There is workplace.stackexchange.com for me to ask about the teamwork ...
    – h22
    Commented Feb 27, 2020 at 16:56

3 Answers 3

9

using directives are certainly acceptable in *.cpp files when C++ authorities like Herb Sutter and Bjarne Stroustrup explicitly say so in their published Core Guidelines:

Use using namespace directives for transition, for foundation libraries (such as std), or within a local scope (only)

However, I believe your question is based on a false premise. You say that prepending std:: to identifiers everywhere clutters the code. This is purely subjective, and most C++ programmers I know (including myself) have the opposite view, i.e. that the std:: makes the code easier to read because standard-library components can easily be distinguished from your own classes and functions.

Now of course, this opposite opinion might be equally subjective, but you also have to consider consistency. After all, you avoid using directives at global scope in header files anyway, so why add different rules for different situations? As a C++ programmer, you are used to seeing std::string and std::vector in header files all the time, so string and vector simply look unusual, even in *.cpp files.

7
  • It's hard to distinguish "experience in a domain" with "growing indifferent to nonsense". I occasionally write C++, and from the outside looking in: seeing std:: everywhere just drowns out my code. It feels like Java's verbosity, but worse, because the tools to remedy the boilerplate already exist, but they're actively being discouraged. It's truly mind boggling to me, honestly.
    – Alexander
    Commented Oct 22, 2020 at 17:45
  • @Alexander-ReinstateMonica: It's also hard to distinguish "growing indifferent to nonense" with "growing indifferent to superficialities". Having std:: just works good enough. Commented Oct 23, 2020 at 7:02
  • Would you think the same about the prefixes that are used by libraries in C? (as their own substitute for namespaces)
    – Alexander
    Commented Oct 26, 2020 at 19:14
  • @Alexander-ReinstateMonica: Sure, why not? Commented Oct 27, 2020 at 15:27
  • You don't find it at all jarring when you jump into a C file and see glutInitialize, glutDoSomething, cvHaarDetectObjects, CV_HAAR_SCALE_IMAGE`, with the same prefixes littered all over?
    – Alexander
    Commented Oct 27, 2020 at 15:48
3

In addition to the other, good and balanced, answer:

  • In headers global scope, I'd say it's quite the consensus to not use using namespace XYZ
  • I don't see any such consensus with regard to source/cpp files: I.e. some find it OK, some frown upon even this.
  • using namespace std or using std::string can be scoped to a local function/scope, which is what I prefer: That way I can even use it in header-inline functions.
  • If I have a function and I use string once, I can just as well write std::string. If the function uses string, vector, ... in multiple places, I prefer the using form.
    • I do find too many :: clutter my code.
4
  • iirc there is also a bit of a difference depending on if you are doing application development of library development.
    – jk.
    Commented Feb 28, 2020 at 12:03
  • There is weak consensus that using namespace should only be used with closed or owned namespaces even in implementation files. Commented Feb 28, 2020 at 13:17
  • 1
    @jk.: For source files? I doubt it. For header files, maybe. If you are doing application development, then you have full control over where and how your header files are included, so the arguments against using namespace at global scope become slightly less relevant, although I think it's still a very bad idea. Commented Feb 28, 2020 at 20:28
  • 3
    By the way, another important aspect is that C++11's auto made many previous uses of using to abbreviate type names obsolete, such as when something like std::map<std::string, std::vector<std::string>>::const_iterator iter can be reduced to auto iter. Commented Feb 28, 2020 at 20:36
2

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.

3
  • 1
    C++ programmers (like myself) seem to be particularly motivated by a single yet memorable bad experience such as obscure source-level bugs. C++ forces programmers to be as explicit (ambiguity-removing) as possible.
    – rwong
    Commented Oct 22, 2020 at 9:11
  • 1
    @rwong I've seen people radically change styles overnight like (2==x) over (x==2) for expressions I've always been a bit more stubborn than that, favoring whatever seems idiomatic when possible and "natural" until I can't make a good argument for it anymore. But the namespace and ADL issues were enough after multiple bugs, not one, for me to favor using directives and declarations. I don't think we can avoid being implicit here. I might even push that using directives/declarations are more explicit because of the existence of ADL/Koenig Lookup.
    – user377672
    Commented Oct 22, 2020 at 9:22
  • 2
    @rwong From my standpoint, using namespace std; int main() {cout << "hello, world\n;}" is more explicit, not less, than int main() {std::cout << "hello, world\n";}, because the latter version requires implicitly relying on ADL to find operator<< in namespace std.
    – user377672
    Commented Oct 22, 2020 at 9:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.