--- title: "User-defined literals (C++)" description: "Describes the purpose and use of user-defined literals in Standard C++." ms.date: "02/10/2020" ms.assetid: ff4a5bec-f795-4705-a2c0-53788fd57609 --- # User-defined literals There are six major categories of literals in C++: integer, character, floating-point, string, boolean, and pointer. Starting in C++ 11, you can define your own literals based on these categories, to provide syntactic shortcuts for common idioms and increase type safety. For example, let's say you have a `Distance` class. You could define a literal for kilometers and another one for miles, and encourage the user to be explicit about the units of measure by writing: `auto d = 42.0_km` or `auto d = 42.0_mi`. There's no performance advantage or disadvantage to user-defined literals; they're primarily for convenience or for compile-time type deduction. The Standard Library has user-defined literals for `std::string`, for `std::complex`, and for units in time and duration operations in the \ header: ```cpp Distance d = 36.0_mi + 42.0_km; // Custom UDL (see below) std::string str = "hello"s + "World"s; // Standard Library UDL complex num = (2.0 + 3.01i) * (5.0 + 4.3i); // Standard Library UDL auto duration = 15ms + 42h; // Standard Library UDLs ``` ## User-defined literal operator signatures You implement a user-defined literal by defining an **operator""** at namespace scope with one of the following forms: ```cpp ReturnType operator "" _a(unsigned long long int); // Literal operator for user-defined INTEGRAL literal ReturnType operator "" _b(long double); // Literal operator for user-defined FLOATING literal ReturnType operator "" _c(char); // Literal operator for user-defined CHARACTER literal ReturnType operator "" _d(wchar_t); // Literal operator for user-defined CHARACTER literal ReturnType operator "" _e(char16_t); // Literal operator for user-defined CHARACTER literal ReturnType operator "" _f(char32_t); // Literal operator for user-defined CHARACTER literal ReturnType operator "" _g(const char*, size_t); // Literal operator for user-defined STRING literal ReturnType operator "" _h(const wchar_t*, size_t); // Literal operator for user-defined STRING literal ReturnType operator "" _i(const char16_t*, size_t); // Literal operator for user-defined STRING literal ReturnType operator "" _g(const char32_t*, size_t); // Literal operator for user-defined STRING literal ReturnType operator "" _r(const char*); // Raw literal operator template ReturnType operator "" _t(); // Literal operator template ``` The operator names in the previous example are placeholders for whatever name you provide; however, the leading underscore is required. (Only the Standard Library is allowed to define literals without the underscore.) The return type is where you customize the conversion or other operations done by the literal. Also, any of these operators can be defined as **`constexpr`**. ## Cooked literals In source code, any literal, whether user-defined or not, is essentially a sequence of alphanumeric characters, such as `101`, or `54.7`, or `"hello"` or **`true`**. The compiler interprets the sequence as an integer, float, const char\* string, and so on. A user-defined literal that accepts as input whatever type the compiler assigned to the literal value is informally known as a *cooked literal*. All the operators above except `_r` and `_t` are cooked literals. For example, a literal `42.0_km` would bind to an operator named _km that had a signature similar to _b and the literal `42_km` would bind to an operator with a signature similar to _a. The following example shows how user-defined literals can encourage callers to be explicit about their input. To construct a `Distance`, the user must explicitly specify kilometers or miles by using the appropriate user-defined literal. You can achieve the same result in other ways, but user-defined literals are less verbose than the alternatives. ```cpp // UDL_Distance.cpp #include #include struct Distance { private: explicit Distance(long double val) : kilometers(val) {} friend Distance operator"" _km(long double val); friend Distance operator"" _mi(long double val); long double kilometers{ 0 }; public: const static long double km_per_mile; long double get_kilometers() { return kilometers; } Distance operator+(Distance other) { return Distance(get_kilometers() + other.get_kilometers()); } }; const long double Distance::km_per_mile = 1.609344L; Distance operator"" _km(long double val) { return Distance(val); } Distance operator"" _mi(long double val) { return Distance(val * Distance::km_per_mile); } int main() { // Must have a decimal point to bind to the operator we defined! Distance d{ 402.0_km }; // construct using kilometers std::cout << "Kilometers in d: " << d.get_kilometers() << std::endl; // 402 Distance d2{ 402.0_mi }; // construct using miles std::cout << "Kilometers in d2: " << d2.get_kilometers() << std::endl; //646.956 // add distances constructed with different units Distance d3 = 36.0_mi + 42.0_km; std::cout << "d3 value = " << d3.get_kilometers() << std::endl; // 99.9364 // Distance d4(90.0); // error constructor not accessible std::string s; std::getline(std::cin, s); return 0; } ``` The literal number must use a decimal. Otherwise, the number would be interpreted as an integer, and the type wouldn't be compatible with the operator. For floating point input, the type must be **`long double`**, and for integral types it must be **`long long`**. ## Raw literals In a raw user-defined literal, the operator that you define accepts the literal as a sequence of char values. It's up to you to interpret that sequence as a number or string or other type. In the list of operators shown earlier in this page, `_r` and `_t` can be used to define raw literals: ```cpp ReturnType operator "" _r(const char*); // Raw literal operator template ReturnType operator "" _t(); // Literal operator template ``` You can use raw literals to provide a custom interpretation of an input sequence that's different than the compiler's normal behavior. For example, you could define a literal that converts the sequence `4.75987` into a custom Decimal type instead of an IEEE 754 floating point type. Raw literals, like cooked literals, can also be used for compile-time validation of input sequences. ### Example: Limitations of raw literals The raw literal operator and literal operator template only work for integral and floating-point user-defined literals, as shown by the following example: ```cpp #include #include // Literal operator for user-defined INTEGRAL literal void operator "" _dump(unsigned long long int lit) { printf("operator \"\" _dump(unsigned long long int) : ===>%llu<===\n", lit); }; // Literal operator for user-defined FLOATING literal void operator "" _dump(long double lit) { printf("operator \"\" _dump(long double) : ===>%Lf<===\n", lit); }; // Literal operator for user-defined CHARACTER literal void operator "" _dump(char lit) { printf("operator \"\" _dump(char) : ===>%c<===\n", lit); }; void operator "" _dump(wchar_t lit) { printf("operator \"\" _dump(wchar_t) : ===>%d<===\n", lit); }; void operator "" _dump(char16_t lit) { printf("operator \"\" _dump(char16_t) : ===>%d<===\n", lit); }; void operator "" _dump(char32_t lit) { printf("operator \"\" _dump(char32_t) : ===>%d<===\n", lit); }; // Literal operator for user-defined STRING literal void operator "" _dump(const char* lit, size_t) { printf("operator \"\" _dump(const char*, size_t): ===>%s<===\n", lit); }; void operator "" _dump(const wchar_t* lit, size_t) { printf("operator \"\" _dump(const wchar_t*, size_t): ===>%ls<===\n", lit); }; void operator "" _dump(const char16_t* lit, size_t) { printf("operator \"\" _dump(const char16_t*, size_t):\n" ); }; void operator "" _dump(const char32_t* lit, size_t) { printf("operator \"\" _dump(const char32_t*, size_t):\n" ); }; // Raw literal operator void operator "" _dump_raw(const char* lit) { printf("operator \"\" _dump_raw(const char*) : ===>%s<===\n", lit); }; template void operator "" _dump_template(); // Literal operator template int main(int argc, const char* argv[]) { 42_dump; 3.1415926_dump; 3.14e+25_dump; 'A'_dump; L'B'_dump; u'C'_dump; U'D'_dump; "Hello World"_dump; L"Wide String"_dump; u8"UTF-8 String"_dump; u"UTF-16 String"_dump; U"UTF-32 String"_dump; 42_dump_raw; 3.1415926_dump_raw; 3.14e+25_dump_raw; // There is no raw literal operator or literal operator template support on these types: // 'A'_dump_raw; // L'B'_dump_raw; // u'C'_dump_raw; // U'D'_dump_raw; // "Hello World"_dump_raw; // L"Wide String"_dump_raw; // u8"UTF-8 String"_dump_raw; // u"UTF-16 String"_dump_raw; // U"UTF-32 String"_dump_raw; } ``` ```Output operator "" _dump(unsigned long long int) : ===>42<=== operator "" _dump(long double) : ===>3.141593<=== operator "" _dump(long double) : ===>31399999999999998506827776.000000<=== operator "" _dump(char) : ===>A<=== operator "" _dump(wchar_t) : ===>66<=== operator "" _dump(char16_t) : ===>67<=== operator "" _dump(char32_t) : ===>68<=== operator "" _dump(const char*, size_t): ===>Hello World<=== operator "" _dump(const wchar_t*, size_t): ===>Wide String<=== operator "" _dump(const char*, size_t): ===>UTF-8 String<=== operator "" _dump(const char16_t*, size_t): operator "" _dump(const char32_t*, size_t): operator "" _dump_raw(const char*) : ===>42<=== operator "" _dump_raw(const char*) : ===>3.1415926<=== operator "" _dump_raw(const char*) : ===>3.14e+25<=== ```