Use namespaces
Today's post is motivated by some past discussion that came up during standardization. The renaming of two views back to their originally proposed names P2501R0. One was a rename from views::all_move
to views::move
.
I'm not speaking or expressing the opinion of the committee here.
The rename was subject to a debate about whether it was a good idea. One reason for being against the undo of the rename was that the standard now has a std::move
and a std::views::move
. Two times the name move
but is well guarded in different namespaces. Of course, with different functionality as well.
The argument for keeping all_move
was to protect people who write code like this:
1 2 3 4 |
|
In this example, the author used using namespace
to get rid of the repetitive typing std::
and, of course, std::views::
.
By doing this, the compiler now finds two functions move
and picks the best matching one. However, the best match in terms of the language, not our expectations. In the case of all_move
, the std::move
version is picked unintentionally.
So far about the introduction.
Let's forget about the proposal. My point is about using namespace
.
Dragging in an entire foreign namespace is bad practice! You must be prepared for trouble if you deliberately pull in a whole, foreign namespace. The key idea behind a namespace is encapsulation. Sparing you trouble. Once you ignore that, the potentially resulting problem is entirely on you.
When is it okay to say using namespace
?
My rule I use is to use using namespace
once I implement a class in a namespace. For example, suppose you I have the following header file:
1 2 3 4 5 6 7 |
|
I would use using Cool
in the implementation as this is my namespace.
1 2 3 4 5 6 7 8 9 10 |
|
What if I need a function or data type from a foreign namespace often?
Sometimes you use functions or data types from other namespaces a lot in a certain implementation file. As an example, assume std::move
. Please don't say using namespace std;
. The better solution here, if you really like to avoid typing std
, is
1 |
|
By that, you make only std::move
visible in your current file. Hopefully, when you write directly beneath that statement, another one using std::views::move
, it becomes apparent that you're asking for trouble.
However, I personally have to rule to avoid using
for foreign data types. Such symbols are, for a reason, in their own namespace. The following are my personal set of rules for namespaces:
- Avoid
using namespace
for foreign types/functions. - Use
using namespace
only for the namespace you currently provide an implementation for. - If you fight with long foreign namespaces prefer
using DATATYPE_OR_FUNCTION;
overusing namespace
. - Stay away from
using namespace
. - Always be precise, even on slides.
Do you want some exercise?
In case you want a little exercise, have a look at the following code and answer yourself:
- Does this code compile?
- What is the output of that program?
- Would the output change if you would change the two
using
lines?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Of course, Compiler Explorer know the truth.
Andreas