Namespaces
Variants

User-defined literals (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Ermöglicht es Ganzzahl-, Gleitkomma-, Zeichen- und Zeichenkettenliteralen, Objekte benutzerdefinierten Typs zu erzeugen, indem ein benutzerdefinierter Suffix definiert wird.

Inhaltsverzeichnis

Syntax

Ein benutzerdefinierter Literal ist ein Ausdruck einer der folgenden Formen

Dezimalliteral ud-suffix (1)
Oktalliteral ud-suffix (2)
Hexadezimalliteral ud-suffix (3)
Binärliteral ud-suffix (4)
Bruchkonstante Exponententeil  (optional) ud-suffix (5)
Ziffernfolge Exponententeil ud-suffix (6)
Zeichenliteral ud-suffix (7)
Zeichenkettenliteral ud-suffix (8)
1-4) benutzerdefinierte Ganzzahlliterale, wie z.B. 12 _km
5-6) benutzerdefinierte Gleitkommaliterale, wie z.B. 0.5 _Pa
7) benutzerdefinierter Zeichenliteral, wie z.B. 'c' _X
8) benutzerdefinierter String-Literal, wie "abd" _L oder u "xyz" _M
decimal-literal - identisch wie in Ganzzahlliteral , eine Dezimalziffer ungleich null gefolgt von null oder mehr Dezimalziffern
octal-literal - identisch wie in Ganzzahlliteral , eine Null gefolgt von null oder mehr Oktalziffern
hex-literal - identisch wie in Ganzzahlliteral , 0x oder 0X gefolgt von einer oder mehr Hexadezimalziffern
binary-literal - identisch wie in Ganzzahlliteral , 0b oder 0B gefolgt von einer oder mehr Binärziffern
digit-sequence - identisch wie in Gleitkommaliteral , eine Folge von Dezimalziffern
fractional-constant - identisch wie in Gleitkommaliteral , entweder eine digit-sequence gefolgt von einem Punkt ( 123 . ) oder eine optionale digit-sequence gefolgt von einem Punkt und einer weiteren digit-sequence ( 1.0 oder .12 )
exponent-part - identisch wie in Gleitkommaliteral , der Buchstabe e oder der Buchstabe E gefolgt von optionalem Vorzeichen, gefolgt von digit-sequence
character-literal - identisch wie in Zeichenliteral
string-literal - identisch wie in Zeichenkettenliteral , einschließlich Raw-Zeichenkettenliteralen
ud-suffix - ein Bezeichner, eingeführt durch eine Literaloperator - oder Literaloperator-Template -Deklaration (siehe unten )

In den Integer- und Fließkomma- Ziffernfolgen sind optionale Trennzeichen ' zwischen beliebigen zwei Ziffern erlaubt.

(since C++14)

Wenn ein Token sowohl auf eine benutzerdefinierte Literalsyntax als auch auf eine reguläre Literalsyntax passt, wird angenommen, dass es sich um ein reguläres Literal handelt (das heißt, es ist unmöglich, LL in 123LL zu überladen).

Wenn der Compiler auf ein benutzerdefiniertes Literal mit dem ud-suffix X stößt, führt er einen unqualified name lookup durch, um nach einer Funktion mit dem Namen operator "" X zu suchen. Wenn die Suche keine Deklaration findet, ist das Programm fehlerhaft. Andernfalls,

1) Für benutzerdefinierte Ganzzahlliterale,
a) wenn der Überladungssatz einen Literaloperator mit dem Parametertyp unsigned long long enthält, wird der benutzerdefinierte Literalausdruck als Funktionsaufruf operator "" X ( n  ULL ) behandelt, wobei n das Literal ohne ud-suffix ist;
b) andernfalls muss der Überladungssatz entweder, aber nicht beide, einen Raw-Literal-Operator oder eine numerische Literal-Operator-Vorlage enthalten. Wenn der Überladungssatz einen Raw-Literal-Operator enthält, wird der benutzerdefinierte Literalausdruck als Funktionsaufruf operator "" X ( " n  ") behandelt;
c) andernfalls, wenn der Überladungssatz eine numerische Literal-Operatorvorlage enthält, wird der benutzerdefinierte Literalausdruck als Funktionsaufruf behandelt operator "" X < ' c1  ' , ' c2  ' , ' c3  ' ..., ' ck  ' > ( ) , wobei c1 .. ck die einzelnen Zeichen von n sind und alle aus dem Basiszeichensatz stammen.
2) Für benutzerdefinierte Gleitkommaliterale,
a) Wenn der Überladungssatz einen Literaloperator mit dem Parametertyp long double enthält, wird der benutzerdefinierte Literalausdruck als Funktionsaufruf operator "" X ( f   L ) behandelt, wobei f das Literal ohne ud-suffix ist;
b) andernfalls muss der Überladungssatz entweder, aber nicht beide, einen Raw-Literal-Operator oder eine numerische Literal-Operator-Vorlage enthalten. Wenn der Überladungssatz einen Raw-Literal-Operator enthält, wird der benutzerdefinierte Literalausdruck als Funktionsaufruf operator "" X ( " f   ") behandelt;
c) andernfalls, wenn der Überladungssatz einen numerischen Literal-Operator-Template enthält, wird der benutzerdefinierte Literalausdruck als Funktionsaufruf behandelt operator "" X < ' c1  ' , ' c2  ' , ' c3  ' ..., ' ck  ' > ( ) , wobei c1 .. ck die einzelnen Zeichen von f sind und alle aus dem Basiszeichensatz stammen.
3) Für benutzerdefinierte String-Literale sei str das Literal ohne ud-suffix :
a) Wenn der Überladungssatz einen String-Literal-Operator-Template mit einem konstanten Template-Parameter enthält, für den str ein gültiges Template-Argument ist, dann wird der benutzerdefinierte Literalausdruck als Funktionsaufruf operator "" X < str > ( ) behandelt;
(seit C++20)
b) andernfalls wird der benutzerdefinierte Literalausdruck als Funktionsaufruf operator "" X ( str, len ) behandelt, wobei len die Länge des String-Literals ohne das abschließende Nullzeichen ist.
4) Für benutzerdefinierte Zeichenliterale wird der benutzerdefinierte Literalausdruck als Funktionsaufruf operator "" X ( ch ) behandelt, wobei ch das Literal ohne ud-suffix ist.
long double operator ""_w(long double);
std::string operator ""_w(const char16_t*, size_t);
unsigned    operator ""_w(const char*);
int main()
{
    1.2_w;    // ruft operator ""_w(1.2L) auf
    u"one"_w; // ruft operator ""_w(u"one", 3) auf
    12_w;     // ruft operator ""_w("12") auf
    "two"_w;  // Fehler: kein passender Literal-Operator
}

Wenn die Verkettung von Zeichenkettenliteralen in Übersetzungsphase 6 stattfindet, werden auch benutzerdefinierte Zeichenkettenliterale verkettet, und ihre ud-suffix e werden für die Verkettung ignoriert, mit der Ausnahme, dass nur ein Suffix auf allen verketteten Literalen erscheinen darf:

int main()
{
    L"A" "B" "C"_x;  // OK: gleiche Bedeutung wie L"ABC"_x
    "P"_x "Q" "R"_y; // Fehler: zwei verschiedene UD-Suffixe (_x und _y)
}

Literaloperatoren

Die von einem benutzerdefinierten Literal aufgerufene Funktion wird als literal operator bezeichnet (oder, falls es sich um ein Template handelt, literal operator template ). Sie wird wie jede andere Funktion oder function template im Namensbereich deklariert (sie kann auch eine Friend-Funktion, eine explizite Instanziierung oder Spezialisierung eines Funktions-Templates sein oder durch eine using-Deklaration eingeführt werden), mit Ausnahme der folgenden Einschränkungen:

Der Name dieser Funktion kann eine von zwei Formen haben:

operator "" Bezeichner (1) (veraltet)
operator benutzerdefinierter-Zeichenkettenliteral (2)
identifier - der identifier , der als ud-suffix für die benutzerdefinierten Literale verwendet wird, die diese Funktion aufrufen
user-defined-string-literal - die Zeichenfolge "" gefolgt, ohne Leerzeichen, von der Zeichenfolge, die zum ud-suffix wird
1) Deklariert einen Literal-Operator.
2) Deklariert einen Literaloperator. Diese Syntax ermöglicht es, Sprachschlüsselwörter und reservierte Bezeichner als ud-suffix es zu verwenden, zum Beispiel operator "" if aus dem Header <complex> .

ud-suffix muss mit dem Unterstrich _ beginnen: Die Suffixe, die nicht mit dem Unterstrich beginnen, sind für die von der Standardbibliothek bereitgestellten Literaloperatoren reserviert. Es darf ebenfalls keine doppelten Unterstriche __ enthalten: Solche Suffixe sind ebenfalls reserviert.

Wenn der Literaloperator eine Vorlage ist, muss er eine leere Parameterliste haben und kann nur einen Template-Parameter besitzen, der ein konstantes Template-Parameterpaket mit Elementtyp char sein muss (in diesem Fall wird er als numerischer Literaloperator-Template bezeichnet):

template<char...>
double operator ""_x();

oder einen konstanten Template-Parameter vom Klassentyp (in diesem Fall wird er als String-Literal-Operator-Template bezeichnet):

struct A { constexpr A(const char*); };
template<A a>
A operator ""_a();
(seit C++20)

Nur die folgenden Parameterlisten sind für Literaloperatoren zulässig:

( const char * ) (1)
( unsigned long long int ) (2)
( long double ) (3)
( char ) (4)
( wchar_t ) (5)
( char8_t ) (6) (seit C++20)
( char16_t ) (7)
( char32_t ) (8)
( const char * , std::size_t ) (9)
( const wchar_t * , std::size_t ) (10)
( const char8_t * , std::size_t ) (11) (seit C++20)
( const char16_t * , std::size_t ) (12)
( const char32_t * , std::size_t ) (13)
1) Literaloperatoren mit dieser Parameterliste sind die Raw-Literaloperatoren , die als Fallback für benutzerdefinierte Ganzzahl- und Gleitkommaliterale verwendet werden (siehe oben)
2) Literaloperatoren mit diesen Parameterlisten sind die bevorzugten Literaloperatoren für benutzerdefinierte Ganzzahlliterale
3) Literaloperatoren mit diesen Parameterlisten sind die bevorzugten Literaloperatoren für benutzerdefinierte Gleitkommaliterale
4-8) Literaloperatoren mit diesen Parameterlisten werden durch benutzerdefinierte Zeichenliterale aufgerufen
9-13) Literaloperatoren mit diesen Parameterlisten werden durch benutzerdefinierte String-Literale aufgerufen

Standardargumente sind nicht erlaubt.

C language linkage ist nicht erlaubt.

Abgesehen von den oben genannten Einschränkungen sind Literaloperatoren und Literaloperatortemplates normale Funktionen (und Funktionsvorlagen). Sie können als inline oder constexpr deklariert werden, sie können internen oder externen Linkage haben, sie können explizit aufgerufen werden, ihre Adressen können genommen werden, usw.

#include <string>
void        operator ""_km(long double); // OK, wird für 1.0_km aufgerufen
void        operator "" _km(long double); // wie oben, veraltet
std::string operator ""_i18n(const char*, std::size_t); // OK
template<char...>
double operator ""_pi(); // OK
float  operator ""_e(const char*); // OK
// Fehler: Suffix muss mit Unterstrich beginnen
float operator ""Z(const char*);
// Fehler: alle Namen, die mit Unterstrich gefolgt von Großbuchstaben beginnen,
// sind reserviert (HINWEIS: ein Leerzeichen zwischen "" und _).
double operator"" _Z(long double);
// OK. HINWEIS: kein Leerzeichen zwischen "" und _.
double operator""_Z(long double);
// OK: Literaloperatoren können überladen werden
double operator ""_Z(const char* args);
int main() {}

Hinweise

Seit der Einführung benutzerdefinierter Literale ist Code, der Format-Makrokonstanten für Ganzzahltypen fester Breite ohne Leerzeichen nach dem vorangehenden Zeichenkettenliteral verwendet, ungültig geworden: std:: printf ( "%" PRId64 " \n " , INT64_MIN ) ; muss ersetzt werden durch std:: printf ( "%" PRId64 " \n " , INT64_MIN ) ; .

Aufgrund von maximal munch müssen benutzerdefinierte Ganzzahl- und Gleitkommaliterale, die auf p , P , (since C++17) e und E enden, wenn sie von den Operatoren + oder - gefolgt werden, im Quellcode durch Leerzeichen oder Klammern vom Operator getrennt werden:

long double operator""_E(long double);
long double operator""_a(long double);
int operator""_p(unsigned long long);
auto x = 1.0_E+2.0;   // Fehler
auto y = 1.0_a+2.0;   // OK
auto z = 1.0_E +2.0;  // OK
auto q = (1.0_E)+2.0; // OK
auto w = 1_p+2;       // Fehler
auto u = 1_p +2;      // OK

Gleiches gilt für den Punktoperator nach einem ganzzahligen oder Gleitkomma-Benutzerdefinierten Literal:

#include <chrono>
using namespace std::literals;
auto a = 4s.count();   // Fehler
auto b = 4s .count();  // OK
auto c = (4s).count(); // OK

Andernfalls wird ein einzelner ungültiger Präprozessor-Zahlentoken (z.B., 1.0 _E + 2.0 oder 4s. count ) gebildet, was dazu führt, dass die Kompilierung fehlschlägt.

Feature-Test-Makro Wert Std Feature
__cpp_user_defined_literals 200809L (C++11) Benutzerdefinierte Literale

Schlüsselwörter

operator

Beispiele

#include <algorithm>
#include <cstddef>
#include <iostream>
#include <numbers>
#include <string>
// used as conversion from degrees (input param) to radians (returned output)
constexpr long double operator""_deg_to_rad(long double deg)
{
    long double radians = deg * std::numbers::pi_v<long double> / 180;
    return radians;
}
// used with custom type
struct mytype
{
    unsigned long long m;
};
constexpr mytype operator""_mytype(unsigned long long n)
{
    return mytype{n};
}
// used for side-effects
void operator""_print(const char* str)
{
    std::cout << str << '\n';
}
#if __cpp_nontype_template_args < 201911
std::string operator""_x2 (const char* str, std::size_t)
{
    return std::string{str} + str;
}
#else // C++20 string literal operator template
template<std::size_t N>
struct DoubleString
{
    char p[N + N - 1]{};
    constexpr DoubleString(char const(&pp)[N])
    {
        std::ranges::copy(pp, p);
        std::ranges::copy(pp, p + N - 1);
    }
};
template<DoubleString A>
constexpr auto operator""_x2()
{
    return A.p;
}
#endif // C++20
int main()
{
    double x_rad = 90.0_deg_to_rad;
    std::cout << std::fixed << x_rad << '\n';
    mytype y = 123_mytype;
    std::cout << y.m << '\n';
    0x123ABC_print;
    std::cout << "abc"_x2 << '\n';
}

Ausgabe:

1.570796
123
0x123ABC
abcabc

Standardbibliothek

Die folgenden Literaloperatoren sind in der Standardbibliothek definiert:

Definiert im Inline-Namensraum std::literals::complex_literals
ein std::complex Literal, das eine rein imaginäre Zahl repräsentiert
(Funktion)
Definiert im Inline-Namensraum std::literals::chrono_literals
ein std::chrono::duration Literal, das Stunden repräsentiert
(Funktion)
ein std::chrono::duration Literal, das Minuten repräsentiert
(Funktion)
ein std::chrono::duration Literal, das Sekunden repräsentiert
(Funktion)
ein std::chrono::duration Literal, das Millisekunden repräsentiert
(Funktion)
ein std::chrono::duration Literal, das Mikrosekunden repräsentiert
(Funktion)
ein std::chrono::duration Literal, das Nanosekunden repräsentiert
(Funktion)
ein std::chrono::year Literal, das ein bestimmtes Jahr repräsentiert
(Funktion)
ein std::chrono::day Literal, das einen Tag eines Monats repräsentiert
(Funktion)
Definiert im Inline-Namensraum std::literals::string_literals
konvertiert ein Zeichenarray-Literal zu basic_string
(Funktion)
Definiert im Inline-Namensraum std::literals::string_view_literals
erstellt einen String-View eines Zeichenarray-Literals
(Funktion)

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
CWG 1473 C++11 Leerzeichen zwischen "" und ud-suffix war
bei der Deklaration von Literaloperatoren erforderlich
optional gemacht
CWG 1479 C++11 Literaloperatoren konnten Standardargumente haben verboten
CWG 2521 C++11 operator "" _Bq war fehlerhaft (keine Diagnose
erforderlich), da es die reservierte Kennung _Bq verwendet
veraltete die Literaloperator-Syntax
mit Leerzeichen zwischen "" und ud-suffix