13 Overloading [over]

13.5 Overloaded operators [over.oper]

13.5.8 User-defined literals [over.literal]

    operator "" identifier

The identifier in a literal-operator-id is called a literal suffix identifier. [ Note: some literal suffix identifiers are reserved for future standardization; see [usrlit.suffix].  — end note ]

A declaration whose declarator-id is a literal-operator-id shall be a declaration of a namespace-scope function or function template (it could be a friend function ([class.friend])), an explicit instantiation or specialization of a function template, or a using-declaration ([namespace.udecl]). A function declared with a literal-operator-id is a literal operator. A function template declared with a literal-operator-id is a literal operator template.

The declaration of a literal operator shall have a parameter-declaration-clause equivalent to one of the following:

const char*
unsigned long long int
long double
const char*, std::size_t
const wchar_t*, std::size_t
const char16_t*, std::size_t
const char32_t*, std::size_t

A raw literal operator is a literal operator with a single parameter whose type is const char*.

The declaration of a literal operator template shall have an empty parameter-declaration-clause and its template-parameter-list shall have a single template-parameter that is a non-type template parameter pack ([temp.variadic]) with element type char.

Literal operators and literal operator templates shall not have C language linkage.

Note: Literal operators and literal operator templates are usually invoked implicitly through user-defined literals ([lex.ext]). However, except for the constraints described above, they are ordinary namespace-scope functions and function templates. In particular, they are looked up like ordinary functions and function templates and they follow the same overload resolution rules. Also, they can be declared inline or constexpr, they may have internal or external linkage, they can be called explicitly, their addresses can be taken, etc.  — end note ]


void operator "" _km(long double);                  // OK
string operator "" _i18n(const char*, std::size_t); // OK
template <char...> int operator "" \u03C0();        // OK: UCN for lowercase pi
float operator ""E(const char*);                    // error: ""E (with no intervening space)
                                                    // is a single token
float operator " " B(const char*);                  // error: non-adjacent quotes
string operator "" 5X(const char*, std::size_t);    // error: invalid literal suffix identifier
double operator "" _miles(double);                  // error: invalid parameter-declaration-clause
template <char...> int operator "" j(const char*);  // error: invalid parameter-declaration-clause

 — end example ]