Title
User-defined literals for Standard Library types
Status
c++14
Section
[time.syn] [string.classes]
Submitter
Howard Hinnant

Created on 2013-07-22.00:00:00 last changed 123 months ago

Messages

Date: 2013-09-26.11:12:18

Proposed resolution:

This wording is relative to N3691.

  1. Modify header <chrono> synopsis, [time.syn], as indicated:

    namespace std {
    […]
    inline namespace literals {
    inline namespace chrono_literals {
    […]
    constexpr chrono::duration<unspecified , nano> operator "" ns(long double);
    
    } // namespace chrono_literals
    } // namespace literals
    
    
    namespace chrono {
        using namespace literals::chrono_literals;
    } // namespace chrono
    
    } // namespace std
    
Date: 2013-09-26.11:12:18

[ 2013-09 Chicago (late night issues) ]

Moved to Ready, after confirming wording reflects the intent of the earlier discussion.

Date: 2013-09-25.20:18:44

[ 2013-09 Chicago ]

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.

This is accomplished by marking namespace std::literals as inline, but for types in their own namespace inside std, then they will need to do this as well. The only case in the current library is chrono.

Marshall Clow provides alternative wording.

Date: 2013-09-25.20:18:44

This paper adds user-defined literals for string, complex and chrono 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:

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 std::literals. [Note: This allows a user either to do a using namespace std::literals; to import all literal operators from the standard available through header file inclusion, or to use using namespace std::string_literals; to just obtain the literals operators for a specific type. — end note]

This isn't how inline namespaces work.

[namespace.def]/p8 says in part:

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). […]

I.e. these literals will appear to the client to already be imported into namespace std. 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:

using namespace std::literals;

or:

using namespace std::literals::string_literals;

prior to use. To get this behavior non-inlined (normal) namespaces must be used.

Originally proposed resolution:

Strike the use of "inline" from each use associated with literals, string_literals, chrono_literals.

My opinion is that this must be done prior to publishing C++14, otherwise we are stuck with this (apparently unwanted) decision forever.

Marshall Clow:

The rationale that I recall was that:

  1. Users could write "using namespace std::literals;" to get all the literal suffixes, or

  2. Users could write "using namespace std::literals::string_literals;" or "using namespace std::literals::chrono_literals;" to get a subset of the suffixes.

To accomplish that, I believe that:

  1. Namespace "std::literals" should not be inline

  2. Namespaces "std::literals::string_literals" and "std::literals::chrono_literals" should be inline

Further details see also reflector message c++std-lib-34256.

Previous resolution from Marshall Clow:

  1. Modify header <chrono> synopsis, [time.syn], as indicated:

    namespace std {
    namespace chrono {
    […]
    } // namespace chrono
    inline namespace literals {
    inline namespace chrono_literals {
    […]
    } // namespace chrono_literals
    } // namespace literals
    } // namespace std
    
  2. Modify header <string> synopsis, [string.classes] p1, as indicated:

    #include <initializer_list>
    
    namespace std {
    […]
    inline namespace literals {
    inline namespace string_literals {
    […]
    }
    }
    }
    
History
Date User Action Args
2014-02-27 17:03:20adminsetstatus: wp -> c++14
2014-02-20 13:52:38adminsetstatus: voting -> wp
2014-02-12 14:19:44adminsetstatus: ready -> voting
2013-09-26 11:12:18adminsetmessages: + msg6629
2013-09-26 11:12:18adminsetstatus: new -> ready
2013-09-25 20:13:11adminsetmessages: + msg6617
2013-08-19 22:13:34adminsetmessages: + msg6562
2013-07-22 00:00:00admincreate