10

Generally, using namespace in global scope is considered as a bad practice. However, according to cppreference, the identifiers not starting with underscore(_) are reserved for standard library in the case of user-defined literals.

the identifier to use as the ud-suffix for the user-defined literals that will call this function. Must begin with the underscore _: the suffixes that do not begin with the underscore are reserved for the literal operators provided by the standard library.

Does that mean I can safely do using namespace std::literals; in global scope?

ikh
  • 10,119
  • 1
  • 31
  • 70
  • 2
    I'm not sure if "safe" is the right thing to ask. I dislike the `using namespace` for anything. I always pick-and-choose the specific identifiers I'm using, right after all my `#include` directives. `using std::literals::string_literals::operator""s` – Eljay Mar 27 '18 at 01:50
  • "*Generally, `using namespace` in global scope is considered as a bad practice*" - not exactly. What is bad practice is `using namespace std` specifically, not `using namespace` in general. – Remy Lebeau Mar 27 '18 at 04:01
  • @RemyLebeau although the linked question is about `namespace std`, the reason why it is bad also applies any other namespaces; the purpose of namespace is to prevent name collision, and `using namespace` breaks it. (The accepted answer of the linked question explains this.) The point of my question is whether `using namespace std::literals` also makes name collision or not. – ikh Mar 27 '18 at 04:04

2 Answers2

4

These user-defined literals are pretty new. You have to understand the Standards body here; they didn't have experience with actual use (unlike say Boost). So they came up with a conservative approach: on one side, the predefined suffixes are in namespace std, on the other side the user-defined literals must start with _.

This indeed leaves an open space in the middle: suffixes that do not start with _ but are defined in the global namespace. As we gain experience with the existing literals, a decision might be made who gets to define such literals.

So, to future-proof your code, you shouldn't cause too much problems for others regardless of what choice is made here in future standards. But does that mean "avoid the using in the global namespace"? No. Each Translation unit gets to make its own choice. In your own .cpp files, do what you like. But you shouldn't affect other Translation units. Therefore the actual rule is:

using namespace std::literals is not safe in headers.

MSalters
  • 173,980
  • 10
  • 155
  • 350
1

From the point of view of the standard, when they say that some names are reserved by the standard library, I'd interpret that as no guaranty of defined behavior, if you break the convention. On the other hand, some compilers may not hold you accountable for breaking the prescribed convention. For example, gcc gives a warning, not an error, for not starting a literal operator identifier with an underscore.

A better formulation here is not whether including

using namespace std::literals;

in global scope is a safe practice, but whether it's a good defensive programming strategy. Putting using namespace foo in global scope is not defensive programming, because doing so defeats the purpose of the namespace, at least in part.

Now, given your specific codebase, you may never run into problems with doing so. But that's only for you to judge. If you are planning on sharing your code with others, I would suggest programming defensively, so that an unwitting user of your code won't have opportunities to run into unexpected situations (even if they don't follow all the conventions, or if the standard is modified in the future).

SU3
  • 5,064
  • 3
  • 35
  • 66
  • Quite reasonable in terms of defensive programming. But a question of language-lawyer still remains, that is, do names in `std::literals` never collide with other user-defined names or not in a legal c++? – ikh Mar 27 '18 at 03:58
  • Agreed. If all standard literals *don't* start with `_`, but all the user-defined ones *do*, then I don't see how they'd collide. But that's a big *if*. – SU3 Mar 27 '18 at 04:00