Introduction

In this article, user-defined literals are explained and examples of their application are given. The examples with user-defined literals
can be compiled only in GCC, version 4.7.0 and above.

Templates To Handle Scientific Quantities

For demonstration, we will consider only the quantities that measure Mass, Length and Time and those derived from
them: Area, Speed, Acceleration, Frequency, Volume, Force, Pressure, etc. Some of the solutions expressed here are similar to [1,2,3].

template<int M, int L, int T>
class Quantity
{
. . .
};

If we try to add (or subtract) two objects whose classes are based on the Quantity template, but have different
values M, L or T, the compiler will signal an error, because their classes will be incompatible. Here is the full definition of the Quantity template:

You may wish to define extra units, like the gallon, the nautical mile, etc. What if we want to print the value of a quantity. In this case, you can either use the member
function getValue, which will give the quantity in the corresponding SI units (since we defined the base units in the SI System), or use the Convert function,
in which case we must explicitly specify the unit that we are converting to. Applying the Convert function is more explicit and, therefore, better.
Here are some examples how we can use this approach:

All the above-mentioned code will execute in Visual C++ 2008/2010/2011/2012 and GCC 4.5 and above.

User-defined Literals in C++11

In C++11 (the new Standard adopted in 2011), it is possible to define new literals, using suffix notation. With this approach, we can write literals 10.0_kg,20.0_g, 50.5_s, etc. Let’s us consider how we can define such literals. If we want to use a floating-point number the general
definition will look as follows (square brackets show that the token is optional):

It looks similar to a function definition. The constexpr token is not mandatory, but it is advisable to use it if you want your literals to be evaluated
at compile time. The return type is the type of the literal that will be created (in our case, Mass, Time, etc).
The literal_suffix token is an identifier: _kg, _g or _s.
The parameter token represents the parameter, that will receive the value of the floating-point value.
If we write 10.0_kg, the value 10.0 will be assigned to the parameter.

The type long double, is the only type allowed for floating-point literals (the maximum available floating-point number).
Here expression represents the expression, which contains the parameter that will evaluated to produce the result.
The definition of the _kg literal can be as follows:

You may ask whether the underscore is really necessary. The answer is no. The standard does not formally prevent you from defining literals without the underscore,
but literals which contain only letters may be used in future extensions. The standard prefixes, like that, are preferred over the user-defined ones. For example,
your attempt to re-define the suffix LL will be ignored. So, it’s good practice to put an underscore.

Another important point: if you define only the long
double parameter you must use only the floating-point number in your literal: like 10.0_kg. You are not allowed to use: 10_kg. But you may define another suffix
with the same name:

The same applies to the operators and unit definitions: they should be all defined with the constexpr token. Now we can define the following conversion macro,
which will enable us to write shorter conversion expressions:

#define ConvertTo(_x, _y) (_x).Convert(1.0_##_y)

Now, instead of

(20 * mile).Convert(kilometre)

we can write

ConvertTo(20.0_mi, km)

You may use your suffix without the underscore as the second parameter of the conversion macro.

A variadic template allows us to use multiple parameters. We define a static array of characters, which is assigned all those values. I, personally, do not see any advantage in using variadic templates in this case. Defining operators with a string parameter is easier, and it's better to use constant expressions without templates anyway.

String Manipulation

It is possible to use constant literals with strings of any characters, in which case the characters should be surrounded by double quotes, for example (the suffixes _UP and _S are user-defined):

"apple"_UP
"zxy"_S

The standard allows also to use UTF_8, Unicode (16 and 32-bit) and wide-character strings (here _w1 , _w2, _w3 and _w4 are user-defined suffixes):

The length parameter is compulsory. The char_type can be one of the follows: char, char16_t, char32_t, wchar_t. You can use such user-defined literals to convert strings to a different representation or to put string literals into containers.

Let us look at a simple example, where all the characters string literal is converted to an uppercase. So the following literals: “apple”_UP, “Apple”_UP, “APPLE”_UP will be converted to an std::string, whose contents will be “APPLE”. The std::string cannot be used in constant expressions, so we are not defining this operator with the contstexpr token:

The char_type can be one of the follows: char, char16_t, char32_t, wchar_t. You can use this syntax in order to incorporate, for example, characters that are not allowed in identifiers, like 'π' or 'µ'.