Ab C ++ 14 sind sie häufig.
C ++ 14 fügt einen Randfall hinzu, in dem Klammern um einen Rückgabewert die Semantik ändern können. Dieses Code-Snippet zeigt zwei deklarierte Funktionen. Der einzige Unterschied besteht in Klammern um den Rückgabewert.
int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))
In der ersten func1
gibt ein int
und in der zweiten eine func1
zurück int&
. Der Unterschied in der Semantik hängt direkt mit den umgebenden Klammern zusammen .
Der auto
Bezeichner in seiner neuesten Form wurde in C ++ 11 eingeführt. In der C ++ - Sprachspezifikation wird Folgendes beschrieben:
Gibt an, dass der Typ der deklarierten Variablen automatisch von ihrem Initialisierer abgeleitet wird. Gibt für Funktionen an, dass der Rückgabetyp ein nachfolgender Rückgabetyp ist oder aus seinen Rückgabeanweisungen abgeleitet wird (seit C ++ 14).
Außerdem hat C ++ 11 den decltype
Spezifizierer eingeführt, der in der C ++ - Sprachspezifikation beschrieben ist :
Überprüft den deklarierten Typ einer Entität oder fragt den Rückgabetyp eines Ausdrucks ab.
[snip]
Wenn das Argument entweder der nicht in Klammern gesetzte Name eines Objekts / einer Funktion oder ein Mitgliedszugriffsausdruck (object.member oder pointer-> member) ist, gibt der decltype den deklarierten Typ der durch diesen Ausdruck angegebenen Entität an.
Wenn das Argument ein anderer Ausdruck vom Typ T ist, dann
a) Wenn die Wertekategorie des Ausdrucks xvalue ist, gibt der Dekltyp T && an
b) Wenn die Wertekategorie des Ausdrucks lvalue ist, gibt der Dekltyp T & an
c) Andernfalls gibt decltype T an
[snip]
Beachten Sie, dass der Name eines Objekts, wenn er in Klammern steht, zu einem l-Wert-Ausdruck wird. Daher sind decltype (arg) und decltype ((arg)) häufig unterschiedliche Typen.
In C ++ 14 war die Verwendung decltype(auto)
für Funktionsrückgabetypen zulässig. In den Originalbeispielen kommt der semantische Unterschied zu Klammern ins Spiel. Wiederholung der ursprünglichen Beispiele:
int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))
decltype(auto)
Ermöglicht die Ableitung des nachfolgenden Rückgabetyps in der Funktion aus der Entität / dem Ausdruck in der return-Anweisung. In der ersten Version return var1;
ist dies effektiv dasselbe wie die Rückgabe des Typs decltype(var1)
(ein int
Rückgabetyp gemäß Regel 1 oben) und im zweiten Fall ist return (var1);
es effektiv dasselbe wie decltype((var1))
(ein int &
Rückgabetyp gemäß Regel 2b).
Die Klammern geben den Rückgabetyp int&
anstelle von an int
, wodurch sich die Semantik ändert. Moral der Geschichte - "Nicht alle Klammern eines Rückgabetyps sind gleich"