What are the good practices for including namespaces in C++ that avoid more typing?

softwareengineering.stackexchange https://softwareengineering.stackexchange.com/questions/207904

  •  29-09-2020
  •  | 
  •  

Вопрос

I am starting out with C++ and almost everywhere I see there is these 2 sentences at the top.

#include <iostream>
using namespace std;

As I understand namespaces are something to keep names separate and have same identifiers in different namespaces. So isn't including std in the beginning undoing all the hard work of creating namespaces? Isn't it better to have something like std::cout when I need a certain function from a particular namespace?

Would including the namespace in the particular function that uses it a good tradeoff between less typing (std::cout vs. cout everywhere) and avoiding the name conflicts(abc in foo and abc in bar avoided using foo::abc and bar::abc)? Something like

int function_using_abc_namespace(int a)
{
    using namespace abc;
    //Rest of the function
}

I wanted to know because avoiding name conflicts is necessary but avoiding more typing is also important. If this isn't good way to get a middle ground then what are the alternatives?

Это было полезно?

Решение

Updated answer based on updated question

It is okay to using namespace std in *.cpp files. It is okay to using namespace std inside function bodies.

Reason: In both cases, they aren't contagious. Contagiousness is the only reason why they shouldn't be used at the global namespace level in header files.

Single-file C++ projects (having just one *.cpp file, no headers, e.g. in programming puzzles and competitive programming) can use them liberally.


Original answer

The only hard rule with using namespace std; in C++ is this:

  • Do not put this in a header file, if this header file needs to be included by multiple source files (*.cpp).
    • Reason: it is contagious.

Other than that, I suggest taking a pragmatic approach to it:

  • Allow importing namespaces as long as it does not cause a compiler warning / ambiguity / conflict.

This brings up the question of: what is the true benefit of having namespaces? The simple answer is disambiguation. But disambiguation for who's benefit?

  • Disambiguation for programmers?

    • This is a relatively minor benefit, because most programmers are already accustomed to object-oriented programming, and the naming of objects is already sufficient for telling about the category and the purpose of that object.
      • However, only human can make sense from the name of objects - computers can't. (See the next point about automated tools.)
    • The human mind is excellent at resolving ambiguity by taking context and domain knowledge into account.
  • Disambiguation for automated tools, such as compilers, automatic comment-to-documentation generators (Javadoc, Doxygen, etc), and automatic refactoring tools?

    • I would argue that this is a more important reason for using namespaces.
    • By putting objects into namespaces, automated tools can present groups of objects as interrelated.
    • This helps hierarchical organization of class documentations, enforcement of package visibility rules, and many other neat things.

Therefore, as long as it does not cause a conflict, feel free to import namespaces.

Другие советы

It's usually recommended not to have using namespace std. Books do it (usually with explanation) just for brevity. Similarly for other namespaces, but there are cases where you might reasonably disagree, and use it anyway.

A very good principle that comes up a lot is that if you're going to make the next person have to learn something, then make sure that they get to amortize that knowledge over a lot of uses.

That means that using namespace std should be part of a coding standard. Either you learn that anything from std is available, and you benefit everywhere. Or you don't learn that but have to type std everywhere. Either position is defensible.

The same principle goes for your internal code. It is OK to have using namespace Foo in your project, but there should be a limited number of namespaces that you import that way. And that list should be imported everywhere. Exactly so that everyone on the project is forced to learn what's in Foo and can then benefit repeatedly. But be very cautious about increasing that list - the people who are inclined to do so are the people who know your code best and who therefore have the least awareness of what it is like for people just learning your code. If you're on the fence, always err on the side of being explicit.

This generalizes much farther. Whenever you're setting up a project, thing long and hard about what people who work with the project need to know. Write down that list. Think hard about adding to it. But anything that is added to that list, should get used heavily so that you get maximum value out of the forced learning.

There is nothing wrong with importing namespaces per se, or it would not be possible.

The trouble starts when importing namespaces with commonly-used and thus likely conflicting identifiers, namespaces with fluid or underspecified content.

And ::std is one such namespace which is open to growth without warning, making previously unambiguous constructs ambiguous, or worse silently changing how a name gets resolved.

So, do not ever use using namespace std;, but have no fear of using namespace std::literals, or using std::cout.

Also, remember that C++ has ADL so most calls need not be qualified.

Лицензировано под: CC-BY-SA с атрибуция
scroll top