<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2278: User-defined literals for Standard Library types</title>
<meta property="og:title" content="Issue 2278: User-defined literals for Standard Library types">
<meta property="og:description" content="C++ library issue. Status: C++14">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2278.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++14">C++14</a> status.</em></p>
<h3 id="2278"><a href="lwg-defects.html#2278">2278</a>. User-defined literals for Standard Library types</h3>
<p><b>Section:</b> 30.2 <a href="https://wg21.link/time.syn">[time.syn]</a>, 27.4 <a href="https://wg21.link/string.classes">[string.classes]</a> <b>Status:</b> <a href="lwg-active.html#C++14">C++14</a>
 <b>Submitter:</b> Howard Hinnant <b>Opened:</b> 2013-07-22 <b>Last modified:</b> 2017-09-07</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#time.syn">issues</a> in [time.syn].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++14">C++14</a> status.</p>
<p><b>Discussion:</b></p>
<p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3642.pdf">This paper</a> adds user-defined literals 
for <code>string</code>, <code>complex</code> and <code>chrono</code> types. It puts each new literal signature in an inline namespace 
inside of std. Section 3.1 of the paper gives the rationale for doing this:
</p>

<blockquote><p>
As a common schema this paper proposes to put all suffixes for user defined literals in separate inline namespaces 
that are below the inline namespace <code>std::literals</code>. [<i>Note:</i> This allows a user either to do a 
<code>using namespace std::literals;</code> to import all literal operators from the standard available through header 
file inclusion, or to use <code>using namespace std::string_literals;</code> to just obtain the literals operators 
for a specific type. &mdash; <i>end note</i>]
</p></blockquote>

<p>This isn't how inline namespaces work.</p>

<p>
9.9.2 <a href="https://wg21.link/namespace.def">[namespace.def]</a>/p8 says in part:
</p>

<blockquote><p>
Members of an inline namespace can be used in most respects as though they were members of the enclosing namespace. 
Specifically, the inline namespace and its enclosing namespace are both added to the set of associated namespaces 
used in argument-dependent lookup (3.4.2) whenever one of them is, and a using- directive (7.3.4) that names the 
inline namespace is implicitly inserted into the enclosing namespace as for an unnamed namespace (7.3.1.1). [&hellip;]
</p></blockquote>

<p>
I.e. these literals will appear to the client to already be imported into namespace <code>std</code>. The rationale in 
the paper appears to indicate that this is not the intended behavior, and that instead the intended behavior is 
to require the user to say:
</p>
<blockquote><pre>
using namespace std::literals;
</pre></blockquote>
<p>
or:
</p>
<blockquote><pre>
using namespace std::literals::string_literals;
</pre></blockquote>
<p>
prior to use. To get this behavior non-inlined (normal) namespaces must be used.
</p>

<p>
Originally proposed resolution:
<p/>
Strike the use of "inline" from each use associated with <code>literals</code>,  <code>string_literals</code>, 
<code>chrono_literals</code>.
<p/>
My opinion is that this must be done prior to publishing C++14, otherwise we are stuck with this 
(apparently unwanted) decision forever.
<p/>
Marshall Clow:
</p>
<blockquote class="note">
<p>
The rationale that I recall was that:
</p>
<ol>
<li><p>Users could write "<code>using namespace std::literals;</code>" to get all the literal suffixes, or</p></li>
<li><p>Users could write "<code>using namespace std::literals::string_literals;</code>" or 
"<code>using namespace std::literals::chrono_literals;</code>" to get a subset of the suffixes.</p></li>
</ol>
<p>
To accomplish that, I believe that:
</p>
<ol style="list-style-type:lower-alpha">
<li><p>Namespace "<code>std::literals</code>" <em>should not</em> be <code>inline</code></p></li>
<li><p>Namespaces "<code>std::literals::string_literals</code>" and "<code>std::literals::chrono_literals</code>" <em>should</em> 
be <code>inline</code></p></li>
</ol>
</blockquote>
<p>
Further details see also reflector message <a href="http://listarchives.isocpp.org/cgi-bin/wg21/message?wg=lib&amp;msg=34256">c++std-lib-34256</a>.
</p>

<p>
Previous resolution from Marshall Clow:
</p>
<blockquote class="note">
<ol>
<li><p>Modify header <code>&lt;chrono&gt;</code> synopsis, 30.2 <a href="https://wg21.link/time.syn">[time.syn]</a>, as indicated:</p>

<blockquote><pre>
namespace std {
namespace chrono {
[&hellip;]
} // namespace chrono
<del>inline</del> namespace literals {
inline namespace chrono_literals {
[&hellip;]
} // namespace chrono_literals
} // namespace literals
} // namespace std
</pre></blockquote>
</li>

<li><p>Modify header <code>&lt;string&gt;</code> synopsis, 27.4 <a href="https://wg21.link/string.classes">[string.classes]</a> p1, as indicated:</p>

<blockquote><pre>
#include &lt;initializer_list&gt;

namespace std {
[&hellip;]
<del>inline</del> namespace literals {
inline namespace string_literals {
[&hellip;]
}
}
}
</pre></blockquote>
</li>
</ol>
</blockquote>

<p><i>[2013-09 Chicago]</i></p>


<p>
After a discussion about intent, the conclusion was that if you hoist a type with a "using" directive, then you should also 
get the associated literal suffixes with the type.
<p/>
This is accomplished by marking namespace <code>std::literals</code> as <code>inline</code>, but for types in their own namespace inside 
<code>std</code>, then they will need to do this as well. The only case in the current library is <code>chrono</code>.
</p>

<p>Marshall Clow provides alternative wording.</p>

<p><i>[2013-09 Chicago (late night issues)]</i></p>

<p>
Moved to Ready, after confirming wording reflects the intent of the earlier discussion.
</p>



<p id="res-2278"><b>Proposed resolution:</b></p>
<p>This wording is relative to N3691.</p>

<ol>
<li><p>Modify header <code>&lt;chrono&gt;</code> synopsis, 30.2 <a href="https://wg21.link/time.syn">[time.syn]</a>, as indicated:</p>

<blockquote><pre>
namespace std {
[&hellip;]
inline namespace literals {
inline namespace chrono_literals {
[&hellip;]
constexpr chrono::duration&lt;<i>unspecified</i> , nano&gt; operator "" ns(long double);

} // namespace chrono_literals
} // namespace literals

<ins>
namespace chrono {
    using namespace literals::chrono_literals;
} // namespace chrono
</ins>
} // namespace std
</pre></blockquote>
</li>

</ol>





</body>
</html>
