Allows integer, floating-point, character, and string literals to produce objects of user-defined type by defining a user-defined suffix.
Syntax
A user-defined literal is an expression of any of the following forms
decimal-literalud-suffix(1) octal-literalud-suffix(2) hex-literalud-suffix(3) binary-literalud-suffix(4) fractional-constantexponent-part(optional)ud-suffix(5) digit-sequenceexponent-partud-suffix(6) character-literalud-suffix(7) string-literalud-suffix(8) 1-4) user-defined integer literals, such as 12_km
5-6) user-defined floating-point literals, such as 0.5_Pa
7) user-defined character literal, such as 'c'_X
8) user-defined string literal, such as "abd"_L or u"xyz"_M
decimal-literal- same as in
, a non-zero decimal digit followed by zero or more decimal digits octal-literal- same as in
, a zero followed by zero or more octal digits hex-literal- same as in
, 0x or 0X followed by one or more hexadecimal digits binary-literal- same as in
, 0b or 0B followed by one or more binary digits digit-sequence- same as in
, a sequence of decimal digits fractional-constant- same as in
, either a digit-sequence followed by a dot (123.) or an optional digit-sequence followed by a dot and another digit-sequence (1.0 or .12) exponent-part- same as in
, the letter e or the letter E followed by optional sign, followed by digit-sequencecharacter-literal- same as in
string-literal- same as in
, including raw string literals ud-suffix- an identifier, introduced by a literal operator or a literal operator template declaration (see
) In the
and
digit sequences, optional separators ' are allowed between any two digits.
(since C++14)If a token matches a user-defined literal syntax and a regular literal syntax, it is assumed to be a regular literal (that is, it's impossible to overload LL in 123LL).
When the compiler encounters a user-defined literal with ud-suffixX, it performs
, looking for a function with the name operator""X. If the lookup does not find a declaration, the program is ill-formed. Otherwise,
1) For user-defined integer literals,
a) if the overload set includes a literal operator with the parameter type unsignedlonglong, the user-defined literal expression is treated as a function call operator""X(nULL), where n is the literal without ud-suffix;
b) otherwise, the overload set must include either, but not both, a raw literal operator or a numeric literal operator template. If the overload set includes a raw literal operator, the user-defined literal expression is treated as a function call operator""X("n");
c) otherwise, if the overload set includes a numeric literal operator template, the user-defined literal expression is treated as a function call operator""X<'c1','c2','c3'...,'ck'>(), where c1..ck are the individual characters of n and all of them are from the
.
2) For user-defined floating-point literals,
a) If the overload set includes a literal operator with the parameter type longdouble, the user-defined literal expression is treated as a function call operator""X(fL), where f is the literal without ud-suffix;
b) otherwise, the overload set must include either, but not both, a raw literal operator or a numeric literal operator template. If the overload set includes a raw literal operator, the user-defined literal expression is treated as a function call operator""X("f");
c) otherwise, if the overload set includes a numeric literal operator template, the user-defined literal expression is treated as a function call operator""X<'c1','c2','c3'...,'ck'>(), where c1..ck are the individual characters of f and all of them are from the
.
3) For user-defined string literals, let str be the literal without ud-suffix:
a) If the overload set includes a string literal operator template with a non-type template parameter for which str is a well-formed template argument, then the user-defined literal expression is treated as a function call operator""X<str>();
(since C++20)b) otherwise, the user-defined literal expression is treated as a function call operator""X(str,len), where len is the length of the string literal, excluding the terminating null character.
4) For user-defined character literals, the user-defined literal expression is treated as a function call operator""X(ch), where ch is the literal without ud-suffix.
longdoubleoperator""_w(longdouble);std::stringoperator""_w(constchar16_t*,size_t);unsignedoperator""_w(constchar*);intmain(){1.2_w;// calls operator ""_w(1.2L)u"one"_w;// calls operator ""_w(u"one", 3)12_w;// calls operator ""_w("12")"two"_w;// error: no applicable literal operator}When string literal concatenation takes place in
, user-defined string literals are concatenated as well, and their ud-suffixes are ignored for the purpose of concatenation, except that only one suffix may appear on all concatenated literals:
intmain(){L"A""B""C"_x;// OK: same as L"ABC"_x"P"_x"Q""R"_y;// error: two different ud-suffixes (_x and _y)}Literal operators
The function called by a user-defined literal is known as literal operator (or, if it's a template, literal operator template). It is declared just like any other
or
at namespace scope (it may also be a friend function, an explicit instantiation or specialization of a function template, or introduced by a using-declaration), except for the following restrictions:
The name of this function can have one of the two forms:
operator ""identifier(1) (deprecated)operatoruser-defined-string-literal(2) identifier- the
to use as the ud-suffix for the user-defined literals that will call this function user-defined-string-literal- the character sequence "" followed, without a space, by the character sequence that becomes the ud-suffix1) Declares a literal operator.
2) Declares a literal operator. This syntax makes it possible to use language keywords and
as ud-suffix es, for example, operator""if from the header
.
ud-suffix must begin with the underscore _: the suffixes that do not begin with the underscore are reserved for the literal operators provided by the standard library. It cannot contain double underscores __ as well: such suffixes are also reserved.
If the literal operator is a template, it must have an empty parameter list and can have only one template parameter, which must be a non-type template parameter pack with element type char (in which case it is known as a numeric literal operator template):
template<char...>doubleoperator""_x();or a non-type template parameter of class type (in which case it is known as a string literal operator template):
structA{constexprA(constchar*);};template<Aa>Aoperator""_a();(since C++20)Only the following parameter lists are allowed on literal operators:
(constchar*)(1) (unsignedlonglongint)(2) (longdouble)(3) (char)(4) (wchar_t)(5) (char8_t)(6) (since C++20)(char16_t)(7) (char32_t)(8) (constchar*,
)(9) (constwchar_t*,
)(10) (constchar8_t*,
)(11) (since C++20)(constchar16_t*,
)(12) (constchar32_t*,
)(13) 1) Literal operators with this parameter list are the raw literal operators, used as fallbacks for integer and floating-point user-defined literals (see above)
2) Literal operators with these parameter lists are the first-choice literal operator for user-defined integer literals
3) Literal operators with these parameter lists are the first-choice literal operator for user-defined floating-point literals
4-8) Literal operators with these parameter lists are called by user-defined character literals
9-13) Literal operators with these parameter lists are called by user-defined string literals
are not allowed.
C
is not allowed.
Other than the restrictions above, literal operators and literal operator templates are normal functions (and function templates), 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.
Run this code
#include<string>voidoperator""_km(longdouble);// OK, will be called for 1.0_kmvoidoperator""_km(longdouble);// same as above, deprecatedstd::stringoperator""_i18n(constchar*,std::size_t);// OKtemplate<char...>doubleoperator""_pi();// OKfloatoperator""_e(constchar*);// OK// error: suffix must begin with underscorefloatoperator""Z(constchar*);// error: all names that begin with underscore followed by uppercase// letter are reserved (NOTE: a space between "" and _).doubleoperator""_Z(longdouble);// OK. NOTE: no space between "" and _.doubleoperator""_Z(longdouble);// OK: literal operators can be overloadeddoubleoperator""_Z(constchar*args);intmain(){}Notes
Since the introduction of user-defined literals, the code that uses
format macro constants for fixed-width integer types
with no space after the preceding string literal became invalid: std::printf("%"PRId64"\n",INT64_MIN); has to be replaced by std::printf("%"PRId64"\n",INT64_MIN);.
Due to
, user-defined integer and floating point literals ending in p, P,(since C++17)e and E, when followed by the operators + or -, must be separated from the operator with whitespace or parentheses in the source:
longdoubleoperator""_E(longdouble);longdoubleoperator""_a(longdouble);intoperator""_p(unsignedlonglong);autox=1.0_E+2.0;// errorautoy=1.0_a+2.0;// OKautoz=1.0_E+2.0;// OKautoq=(1.0_E)+2.0;// OKautow=1_p+2;// errorautou=1_p+2;// OKSame applies to dot operator following an integer or floating-point user-defined literal:
#include<chrono>usingnamespacestd::literals;autoa=4s.count();// Errorautob=4s.count();// OKautoc=(4s).count();// OKOtherwise, a single invalid preprocessing number token (e.g., 1.0_E+2.0 or 4s.count) is formed, which causes compilation to fail.
Feature-test macroValueStdFeature
(C++11)User-defined literals Keywords
Examples
Run this code
#include<algorithm>#include<cstddef>#include<iostream>#include<numbers>#include<string>// used as conversion from degrees (input param) to radians (returned output)constexprlongdoubleoperator""_deg_to_rad(longdoubledeg){longdoubleradians=deg*std::numbers::pi_v<longdouble>/180;returnradians;}// used with custom typestructmytype{unsignedlonglongm;};constexprmytypeoperator""_mytype(unsignedlonglongn){returnmytype{n};}// used for side-effectsvoidoperator""_print(constchar*str){std::cout<<str<<'\n';}#if __cpp_nontype_template_args < 201911std::stringoperator""_x2(constchar*str,std::size_t){returnstd::string{str}+str;}#else // C++20 string literal operator templatetemplate<std::size_tN>structDoubleString{charp[N+N-1]{};constexprDoubleString(charconst(&pp)[N]){std::ranges::copy(pp,p);std::ranges::copy(pp,p+N-1);}};template<DoubleStringA>constexprautooperator""_x2(){returnA.p;}#endif // C++20intmain(){doublex_rad=90.0_deg_to_rad;std::cout<<std::fixed<<x_rad<<'\n';mytypey=123_mytype;std::cout<<y.m<<'\n';0x123ABC_print;std::cout<<"abc"_x2<<'\n';}Output:
1.570796 123 0x123ABC abcabc Standard library
The following literal operators are defined in the standard library:
Defined in inline namespace std::literals::complex_literals
operator""ifoperator""ioperator""il
(C++14)
a
literal representing purely imaginary number
(function)
Defined in inline namespace std::literals::chrono_literals
(C++14)
a
literal representing hours
(function)
(C++14)
a
literal representing minutes
(function)
(C++14)
a
literal representing seconds
(function)
(C++14)
a
literal representing milliseconds
(function)
(C++14)
a
literal representing microseconds
(function)
(C++14)
a
literal representing nanoseconds
(function)
(C++20)
a std::chrono::year literal representing a particular year
(function)
(C++20)
a std::chrono::day literal representing a day of a month
(function)
Defined in inline namespace std::literals::string_literals
(C++14)
converts a character array literal to basic_string
(function)
Defined in inline namespace std::literals::string_view_literals
(C++17)
creates a string view of a character array literal
(function)
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior
C++11 whitespace between "" and ud-suffix was
required in the declaration of literal operators made optional
C++11 literal operators could have default arguments prohibited
C++11 operator""_Bq was ill-formed (no diagnostic
required) because it uses the reserved identifier _Bqdeprecated the literal operator syntax
with whitespace between "" and ud-suffix