Pfeiloperator (->) in der Funktionsüberschrift

127

Ich bin auf folgenden Code gestoßen:

template <typename T, typename T1> auto compose(T a, T1 b) -> decltype(a + b) {
   return a+b;
}

Eines kann ich nicht verstehen:

Wo kann ich herausfinden, was der Pfeiloperator ( ->) in der Funktionsüberschrift bedeutet? Ich denke rein logisch, dass der ->Operator einen Typ bestimmt, autoauf den abgeleitet wird, aber ich möchte dies klarstellen. Ich kann keine Informationen finden.

user1234567
quelle
2
Es ist Teil der Syntax des nachfolgenden Rückgabetyps. Siehe stackoverflow.com/a/4113390/962089
chris
2
Es ist kein Operator, sondern Teil der Syntax.
Texasbruce
1
Als Antwort auf "Wo kann ich lesen?" Ist die C ++ - Spezifikation am maßgeblichsten. Ohne Mittel oder ohne den Wunsch, Geld auszugeben, ist der letzte Arbeitsentwurf oft nah genug und kostenlos. Diese Spezifikationen sind hochtechnologisch. Wenn Sie mit dem Lesen von ISO-Spezifikationen nicht vertraut sind, versuchen Sie es mit cplusplus.com oder cppreference.com oder anderen solchen Websites, die nicht maßgeblich sind, aber normalerweise sehr genau. Hinweis: Der nachfolgende Rückgabetyp kann ab C ++ 14 weggelassen werden.
Les

Antworten:

205

In C ++ 11 gibt es zwei Syntaxen für die Funktionsdeklaration:

    Rückgabetyp Bezeichner ( Argumentdeklarationen ... )

und

    auto Bezeichner ( Argument-Deklarationen ... ) -> return_type

Sie sind gleichwertig. Nun, wenn sie gleichwertig sind, warum möchten Sie diese jemals verwenden? Nun, C ++ 11 hat diese coole decltypeSache eingeführt, mit der Sie die Art eines Ausdrucks beschreiben können. Daher möchten Sie möglicherweise den Rückgabetyp aus den Argumenttypen ableiten. Also versuchst du:

template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);

und der Compiler wird Ihnen sagen, dass er nicht weiß was aund bin der istdecltype Argument sind. Das liegt daran, dass sie nur von der Argumentliste deklariert werden.

Sie können das Problem leicht declvalumgehen, indem Sie die bereits deklarierten Vorlagenparameter verwenden. Mögen:

template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);

außer dass es jetzt sehr ausführlich wird. Daher wurde die alternative Deklarationssyntax vorgeschlagen und implementiert, und jetzt können Sie schreiben

template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);

und es ist weniger ausführlich und die Scoping-Regeln mussten nicht geändert werden.


C ++ 14 Update: C ++ 14 erlaubt auch nur

    auto Bezeichner ( Argument-Deklarationen ... )

Solange die Funktion vor der Verwendung vollständig definiert ist und alle returnAnweisungen denselben Typ haben. Die ->Syntax bleibt für öffentliche Funktionen (im Header deklariert) nützlich, wenn Sie den Text in der Quelldatei ausblenden möchten. Etwas offensichtlich ist dies mit Vorlagen nicht möglich, aber es gibt einige konkrete Typen (die normalerweise über die Metaprogrammierung von Vorlagen abgeleitet werden), die ansonsten schwer zu schreiben sind.

Jan Hudec
quelle
2
sehr gute, ordentliche und informative Antwort @Jan Hudec. Daumen hoch. Gibt es etwas geändert in C++14als ich autofür returnTyp in einer solchen Funktion , ohne die Notwendigkeit für den -> decltype(a + b)Teil. Ist es inzwischen überflüssig oder gibt es andere Fälle, in denen es noch verwendet werden sollte? oder ist es eine compilerspezifische Erweiterung?
Shadi
1
@Shadi, C ++ 14 enthält N3638 , das den Abzug des als autoohne ->Notation deklarierten Rückgabetyps ermöglicht , solange die Funktion vor der Verwendung vollständig definiert ist und alle returnAnweisungen auf denselben Typ abgeleitet werden. Die ->Notation ist weiterhin nützlich, wenn Sie den Abzug für öffentliche Funktionen verwenden möchten, während Sie den Text in der Quelldatei ausblenden.
Jan Hudec
23

Im Klartext heißt es, dass der Rückgabetyp der abgeleitete Typ der Summe von aund ist b.

Murrekatt
quelle