Gemäß [5/8] und [7.1.7.2/4] (Arbeitsentwurf):
decltype
-Spezifizierers ist ein nicht evaluierter Operand
Betrachten Sie den folgenden Code:
%Vor% Es versteht sich von selbst, dass f
und g
tatsächlich nicht ausgewertet werden.
Auf der anderen Seite hat die Funktion h
einen auto
Rückgabetyp, der aus seinem Körper abgeleitet ist, also aus seinen Argumenten und damit aus dem abgeleiteten Typ T
.
Kann es in diesem Fall immer noch als unevaluierter Operand angesehen werden?
Ich meine, es scheint mir, dass im Kontext von decltype
die Funktion h
muss ausgewertet werden, um zu wissen, was der tatsächliche Rückgabetyp ist.
Ich bin mir ziemlich sicher, dass der Arbeitsentwurf stimmt, die Frage ist: Was ist falsch in meinen Überlegungen?
Um den mit decltype(h(42))
gekennzeichneten Typ zu ermitteln, muss der Compiler den Template-Argumentabzug für h
ausführen und die Template-Spezialisierung h<int>
instanziieren, um seinen Rumpf zu untersuchen und den Rückgabetyp zu bestimmen. Dies ist nicht gleich dem Auswerten von h(42)
; Wenn beispielsweise h
irgendwelche Nebeneffekte wie das Drucken einer Nachricht enthält, treten diese Nebenwirkungen nicht auf.
Kann es in diesem Fall immer noch als unevaluierter Operand angesehen werden? ich Es scheint mir, dass im Zusammenhang mit der Deklaration der Die Funktion h muss ausgewertet werden, um zu wissen, was der tatsächliche Rückgabetyp ist.
Es ist immer noch ein ungeprüfter Kontext. Als Brains Antwort (was die kürzere Antwort ist) erklärt.
Der C ++ - Standard spricht über den Prozess der Ableitung von Template-Argumenten und die Substitution von Argumenten für Funktionsvorlagen: [temp.deduct / 7] (Hervorhebung von mir) :
Die Ersetzung findet in allen Typen und Ausdrücken statt, die in verwendet werden der Funktionstyp und in Template-Parameterdeklarationen. Das Ausdrücke enthalten nicht nur konstante Ausdrücke wie solche, die erscheinen in Array-Grenzen oder als Nicht-Typ-Template-Argumente aber auch allgemeine Ausdrücke (d. h. nicht konstante Ausdrücke) in
sizeof
,decltype
und andere Kontexte, die nicht konstante Ausdrücke zulassen. die Substitution läuft in lexikalischer Reihenfolge ab und stoppt, wenn eine Bedingung, die bewirkt, dass der Abzug fehlschlägt.
Sie können mit dem Lesen aus dem ersten Absatz beginnen, um detailliertere Informationen zum Abzug von Vorlagenargumenten zu erhalten.
(Hinweis: Alle zitierten Absätze sind teilweise wiedergegeben, klicken Sie auf die Abschnitt-Links, um den vollständigen Absatz zu sehen) :
Da Sie bereits über decltype
und nicht bewertete Kontexte Bescheid wissen und relevante Abschnitte zitiert haben, können wir diese überspringen und mit auto
...
[dcl.spec.auto/1] : Mit den Typenbezeichnern
auto
unddecltype(auto)
wird a bezeichnet Platzhaltertyp , der später durch einen Abzug von einem ersetzt wird Initialisierer ....
Eine Ansicht von Platzhaltertypen :
[dcl.spec.auto/2] : Der Platzhaltertyp kann mit einem Funktionsdeklarator erscheinen ... ... Wenn der deklarierte Rückgabetyp der Funktion einen Platzhalter enthält Geben Sie ein, der Rückgabetyp der Funktion wird von nicht verworfen abgeleitet
return
-Anweisungen, falls vorhanden, im Hauptteil der Funktion
Über Platzhalter-Typ-Abzug :
[dcl.type.auto.deduct / 1] : Platzhaltertypabzug ist der Vorgang, bei dem ein Typ, der a enthält Platzhaltertyp wird durch einen abgeleiteten Typ ersetzt.
Ableiten von Platzhaltern Rückgabetypen:
[typ.auto.deduct / 4] : Wenn der Platzhalter der automatische Typbezeichner ist, wird der abgeleitete Typ
T'
Ersetzen vonT
wird mithilfe der Regeln für template-Argument bestimmt Abzug
Wenn die Geschichte nicht sehr klar ist, sollten Sie die gesamten Abschnitte für jeden zitierten Absatz lesen.