1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
In addition to the well-known literals, like numerical constants (with or
without suffixes), character constants and string (textual) literals, bf(C++)
also supports
emi(user-defined literals), also known as emi(extensible literals).
A user-defined literal is defined by a function (see also section ref(UDL))
that must be defined at namespace scope. Such a function is called a
i(literal operator).
A literal operator cannot be a class member function. The names of a
literal operator must start with an
hi(identifier: initial underscore) underscore, and a literal operator is
used (called) by em(suffixing) its name (including the underscore) to the
argument that must be passed to it . Assuming tt(_NM2km) (nautical mile to km)
is the name of a literal operator, then it could be called as tt(100_NM2km),
producing, e.g., the value 185.2.
Using tt(Type) to represent the return type of the literal operator
its generic declaration looks like this:
verb(
Type operator "" _identifier(parameter-list);
)
The blank space trailing the empty string is required. The parameter lists
of literal operators can be:
itemization(
itt(unsigned long long int). It is used as, e.g., tt(123_identifier). The
argument to this literal operator can be decimal constants,
binary constants (initial i(0b)), octal constants (initial 0) and
hexadecimal constants (initial 0x);
itt(long double). It is used as, e.g., tt(12.25_NM2km);
itt(char const *text). The tt(text) argument is an NTBS. It is
used as, e.g., tt(1234_pental). The argument must em(not) be given
double quotes, and must represent a numeric constant, as also expected
by literal operators defining tt(unsigned long long int)
parameters.
itt(char const *text, size_t len). Here, the compiler determines tt(len)
as if it had called tt(strlen(text)). It is used as, e.g.,
tt("hello"_nVowels);
itt(wchar_t const *text, size_t len), same as the previous one, but
accepting a string of tt(wchar_t) characters. It is used as, e.g.,
tt(L"1234"_charSum);
itt(char16_t const *text, size_t len), same as the previous one, but
accepting a string of tt(char16_t) characters. It is used as, e.g.,
tt(u"utf 16"_uc);
itt(char32_t const *text, size_t len), same as the previous one, but
accepting a string of tt(char32_t) characters. It is used as, e.g.,
tt(U"UTF 32"_lc);
)
If literal operators are overloaded the compiler will pick the literal
operator requiring the least `effort'. E.g., 120 is processed by a literal
operator defining a tt(unsigned long long int) parameter and not by its
overloaded version, defining a tt(char const *) parameter. But if overloaded
literal operators exist defining tt(char const *) and tt(long double)
parameters then the operator defining a tt(char const *) parameter is used
when the argument 120 is provided, while the operator defining a tt(long
double) parameter is used with the argument 120.3.
A literator operator can define any return type. Here is
an example of a definition of the tt(_NM2km) literal operator:
verb(
double operator "" _NM2km(char const *nm)
{
return std::stod(nm) * 1.852;
}
double value = 120_NM2km; // example of use
)
Of course, the argument could also have been a tt(long double)
constant. Here's an alternative implementation, explicitly expecting a tt(long
double):
verb(
double constexpr operator "" _NM2km(long double nm)
{
return nm * 1.852;
}
double value = 450.5_NM2km; // example of use
)
A numeric constant can also be processed completely at compile-time.
Section ref(UDL) provides the details of this type of literal operator.
Arguments to literal operators are themselves always constants. A literal
operator like tt(_NM2km) cannot be used to convert, e.g., the value of a
variable. A literal operator, although it is defined as functinon, cannot be
called like a function. The following examples therefore
result in compilation errors:
verb(
double speed;
speed_NM2km; // no identifier 'speed_NM2km'
_NM2km(speed); // no function _NM2km
_NM2km(120.3); // no function _NM2km
)
|