20

C++14 includes standard-defined literals for, amongst other things, std::string and various timespans from the <chrono> header.

To use them you must say using namespace std::literals; (or some variation depending on exactly which literals you want, as they're in a variety of inline namespaces).

All this is good, but I'm curious as to why the using declaration is required. UDLs without a leading underscore are reserved for the implementation, so there is no possibility that "hello world"s could ever mean anything else in a standard-conforming programme.

So why isn't #include <string> sufficient to bring the literal conversion function into scope? Why must I explicitly include the literal namespace?

EDIT: N3531 is the most recent version of the proposal I could find -- unfortunately it doesn't discuss the motivation for putting things in a namespace but only says:

One can summarize the requirements of the [Portland] discussion as follows:

  • use an inline namespace for a (group of related) UDL operator(s)
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
Tristan Brindle
  • 16,281
  • 4
  • 39
  • 82
  • 2
    Probably for the same reason user-defined literals must start with `_`: [forward compatibility](http://en.wikipedia.org/wiki/Forward_compatibility). They anticipate adding more literals at some point in the future, and I imagine they put them in different namespaces to avoid naming conflicts. – Cornstalks Oct 27 '14 at 14:56
  • 1
    @Close voter: I highly doubt this is opinion based. The standards committee made a decision. This is asking *why* they made the decision they did. Which isn't based on opinion. It's based on historical discussions and decisions within the committee that are a matter of fact. – Cornstalks Oct 27 '14 at 14:58
  • "UDLs without a leading underscore are reserved for the implementation" Where, and in what version? – Ben Voigt Oct 27 '14 at 15:03
  • Ahh, section `[usrlit.suffix]`, and it's been there since at least draft n3485. So there should be no code written that predates the requirement. – Ben Voigt Oct 27 '14 at 15:04

3 Answers3

13

There already are two UDLs named s: one for strings and one for seconds. Due to the understandably terse names of suffixes, they chronically suffer from name conflicts, so pouring all of them into one namespace cannot go well for long. Hence it was decided that they be put into inline namespaces, which allow for both unambiguous (using namespace std::literals::chrono_literals) and simple using directives (using namespace std).

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • 1
    There can never be another `s` suffix in the global namespace, because all non-standard UDLs must begin with an underscore. – Tristan Brindle Oct 27 '14 at 15:04
  • 3
    @TristanBrindle ... imagine for the sake of this argument that the standard committee itself wanted to introduce a second `operator"" s`. – Columbo Oct 27 '14 at 15:05
  • 1
    @TristanBrindle: There are three stakeholders here: The standard, the platform/implementation/system libraries, and the end developer. Only the last of these is prohibited from using UDL suffixes without leading underscore. – Ben Voigt Oct 27 '14 at 15:06
  • 2
    To make your example even more realistic, imagine if `better_string` was a [`string_view`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3762.html). – Cornstalks Oct 27 '14 at 15:18
  • 1
    @Cornstalks The referenced paper N3531 actually mentions `string_view`, and suggests that it should be given the suffix `sv`. – Tristan Brindle Oct 27 '14 at 15:20
  • I doubt that the standard would ever do that though. This could potentially break code using `using namespace std::literals;`. – Morwenn Oct 28 '14 at 13:58
  • @Morwenn What would prevent the standard from introducing a second (potentially nested) namespace for other literals? – Columbo Oct 28 '14 at 15:39
  • @Loopunroller No particular reason, but that just sounds unlikely. – Morwenn Oct 28 '14 at 21:37
8

the standard library already defines multiple versions of what s can mean:

  1. It can be used to define a string literal.
  2. It can be used to define a chrono::seconds literal.

One is based on a string literal, one is based on an integer or a double literal, of course, i.e., they can actually coexist. However, I'd expect that there may be more uses of s in the future. Thus, having to choose which namespaces are imported rather than getting any imposed on you seems like a reasonable approach.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
1

Look at paper N2765. UDLs are hooked into the regular name lookup process. As string literals have common string types, there's a large chance of a collision if you ignored namespaces.

MSalters
  • 173,980
  • 10
  • 155
  • 350