Werden benutzerdefinierte Literale zur Kompilierzeit oder zur Laufzeit aufgelöst?

8

Ich frage mich, weil vordefinierte Literale wie ULL , f usw. offensichtlich zur Kompilierzeit aufgelöst werden. Der Standard (2.14.8 [lex.ext]) scheint dies nicht zu definieren, scheint aber zur Laufzeit zu tendieren:

  

[2.14.8 / 2]
  Ein benutzerdefiniertes Literal wird als Aufruf für eine literale Operator- oder Literaloperatorvorlage (13.5.8) behandelt. Zu   Bestimmen Sie die Form dieses Aufrufs für ein gegebenes benutzerdefiniertes Literal L mit ud-Suffix X, der Literal-Operator-ID   deren Literal-Suffix-ID X ist, wird im Kontext von L unter Verwendung der Regeln für unqualifizierten Namen nachgeschlagen   Nachschlagen (3.4.1). Sei S die Menge der Deklarationen, die bei dieser Suche gefunden werden. S soll nicht leer sein.
(Hervorhebung meins.)

Für mich scheint dies jedoch unnötigen Laufzeitaufwand zu verursachen, da Literale nur an Werte angehängt werden können, die zur Kompilierzeit verfügbar sind, wie zum Beispiel 13.37f oder "hello"_x (wobei _x ein benutzerdefinierter Wert ist) -literal).
Dann haben wir das templated user-defined-literal bekommen, das im Standard-AFAICS nie wirklich definiert wird (d. H., Es wird kein Beispiel gegeben, bitte beweisen Sie, dass ich falsch liege). Wird diese Funktion zur Kompilierzeit irgendwie magisch aufgerufen oder läuft sie noch?

    
Xeo 16.04.2011, 03:15
quelle

2 Antworten

6

Ja, Sie erhalten einen Funktionsaufruf. Funktionsaufrufe können jedoch aufgrund von constexpr literal Operatorfunktionen kompilierungszeitkonstante Ausdrücke sein.

Ein Beispiel finden Sie hier . Als ein weiteres Beispiel, um die erweiterte Form von constexpr Berechnungen zu zeigen, die von FDIS erlaubt ist, können Sie Literale der Kompilierungszeit base-26 verwenden, die Sie tun können

%Vor%

Mit "bcd-"_26 wird ein throw-Ausdruck ausgewertet, wodurch der Rückgabewert nicht konstant wird. Im Gegenzug verursacht es die Verwendung von "bcd-"_26 als konstanten Ausdruck, um schlecht geformt zu werden, und jede nicht konstante Verwendung, die zur Laufzeit geworfen wird. Die erlaubte Form "bcd"_26 ergibt einen konstanten Ausdruck des jeweiligen berechneten Wertes.

Beachten Sie, dass das Lesen aus Zeichenfolgenliteralen vom FDIS nicht explizit zugelassen wird, es stellt jedoch kein Problem dar und GCC unterstützt dies (die Zeichen-L-Wert-Referenz ist ein konstanter Ausdruck und der Wert des Zeichens ist zum Zeitpunkt der Kompilierung bekannt). IMO wenn man schielt, kann man FDIS lesen, als ob das erlaubt ist.

  

Dann haben wir das templated user-defined-literal, das nie wirklich im Standard-AFAICS definiert wird (d. h., es wird kein Beispiel gegeben, bitte beweisen Sie mich falsch)

Die Behandlung von Literalen als Aufruf von Vorlagen für literale Operatoren ist in 2.14.8 definiert. Weitere Beispiele finden Sie unter 13.5.8, die Details zu den literalen Operatorfunktions- / Funktionsvorlagen selbst enthalten.

  

Wird diese Funktion irgendwie zur Kompilierzeit magisch aufgerufen oder läuft sie noch?

Das Schlüsselwort ist Funktionsaufrufsubstitution . Siehe 7.1.5.

    
Johannes Schaub - litb 16.04.2011, 03:23
quelle
0

@Johannes S ist natürlich korrekt, aber ich möchte klar hinzufügen (da ich dem gegenüber stand), dass selbst für constexpr benutzerdefinierte Literale die Parameter nicht als constexpr oder betrachtet werden Kompilierzeitkonstante, zum Beispiel in dem Sinne, dass sie nicht als Integer-Konstanten für Templates verwendet werden können.

Außerdem geben nur solche Dinge eine Kompilierzeitauswertung:

%Vor%

Also, das wird nicht kompiliert. Aber das wird:

%Vor%

Und Folgendes ist nicht erlaubt:

%Vor%

Das ist ärgerlich, aber natürlich, wenn man bedenkt, dass (andere) conexpr-Funktionen auch während der Ausführung aufgerufen werden können.

Nur für Integer-benutzerdefinierte Literale ist es möglich, die Kompilierzeitverarbeitung zu erzwingen , indem Sie das Vorlagenformular verwenden. Beispiele in meiner Frage und selbst beantworten: Ссылка

    
Johan Lundberg 22.12.2012 15:23
quelle