28

In order to use operator""s for std::string you have to do using namespace std::string_literals. But user-defined literals that don't begin with _ are reserved, so possible conflict can't be an excuse. The other operator""s is from std::chrono but that's for int literals, so there's no conflict there either.

What's the reason for this?

user4375981
  • 405
  • 4
  • 7
  • Oh man... I remember seeing a talk about this, either CppCon or Boostcon, but I can't remember why this was. – Borgleader Dec 18 '14 at 22:05
  • While I don't know the exact reason, it seems reasonable to avoid polluting the global namespace which such a short suffix. – Aleph Dec 18 '14 at 22:06
  • 1
    @Borgleader https://www.youtube.com/watch?v=dTeKf5Oek2c It's at the beginning of the video. –  Dec 19 '14 at 01:26
  • @remyabel You are my savior. Thank you so much for finding it for me! – Borgleader Dec 19 '14 at 01:38
  • Possible duplicate of [Why aren't C++14 standard-defined literals in the global namespace by default?](http://stackoverflow.com/questions/26590165/why-arent-c14-standard-defined-literals-in-the-global-namespace-by-default) – Mikhail Mar 10 '16 at 16:29

1 Answers1

25

There are actually two reasons why literals are put into namespaces:

  1. It is considered undesirable that users would use using namespace std; just to get hold of the corresponding literals. Having the literals declared in namespaces specific to these doesn't cause the problem.
  2. Depending on the domain it may be desirable to use s as the suffix for something else. There is already another suffix s to mean seconds but they don't really conflict.

In the video of STL's CppCon 2014 talk (posted by remyable in a comment) Stephan T. Lavavej explains the overall design of the literals in C++14 and its pretty clear that they are not supposed to be in the global namespace! Instead, the literal suffixes in the standard library live in a hierarchy of inline namespaces giving users fine-grained control over the literals being made available. For example, the literal suffix for strings is declared like this (21.3 [string.classes] paragraph 1):

namespace std {
    inline namespace literals {
        inline namespace string_literals {
            string operator"" s(char const* str, size_t len);
        }
    }
}

This hierarchy of inline namespaces makes it possible for users to get the appropriate choice of literal suffixes:

  • using namespace std; - you get everything in the standard C++ library, including the literal suffixes, without any qualification.
  • using namespace std::literals; - you get all literal suffixes defined in the standard C++ library.
  • using namespace std::string_literals; - you get all literal suffixes applicable to strings.
  • using namespace std::literals::string_literals; - yes, you can do that but you really shouldn't: that's equivalent to using namespace std::string_literals;.

Clearly, the committee wouldn't have gone to that much effort if it had considered the idea viable to just pollute the global namespace with literal suffixes, although they can't even conflict with any user literal suffixes.

Casey
  • 41,449
  • 7
  • 95
  • 125
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • I'm not convinced. User non-standard library code can't declare `operator""s` anyway, or can it? – milleniumbug Dec 18 '14 at 22:12
  • 2
    @milleniumbug: correct: user-defined literals need to start with an `_`. The conflict addressed isn't with user code but rather with other standard library classes. Off-hand I can't think of a convincing example but once we got a networking library it may be cool to create a socket using `"127.0.0.1:80"s`. ... and the other argument, not wanting to mandate polluting code with `using namespace std;` holds anyway: as far as I know you can't have selective `using`-declaration just for a literal operator. – Dietmar Kühl Dec 18 '14 at 22:16
  • 1
    @milleniumbug The proposed `string_view` is another potential candidate for an `""s` literal, although it has also used `""sv` in the past to avoid conflict. (It has no literal operator at all in the current draft.) There’s no telling which solution, if any, will be retained (e.g. concurrent `""s` literals in different namespaces or otherwise). – Luc Danton Dec 20 '14 at 07:12
  • 7
    The flip side of this design decision is that there's no reasonable way to use standard user-defined-literals in a header file without violating the "no `using` directives in headers" guideline. – Casey Feb 18 '15 at 18:19