In c ++ 14 wird das decltype(auto)
Idiom eingeführt.
In der Regel wird verwendet, um auto
Deklarationen die Verwendung der decltype
Regeln für den angegebenen Ausdruck zu ermöglichen .
Auf der Suche nach Beispielen für die "gute" Verwendung des Idioms kann ich nur an folgende Dinge denken (von Scott Meyers ), nämlich für den Abzugstypabzug einer Funktion :
template<typename ContainerType, typename IndexType> // C++14
decltype(auto) grab(ContainerType&& container, IndexType&& index)
{
authenticateUser();
return std::forward<ContainerType>(container)[std::forward<IndexType>(index)];
}
Gibt es andere Beispiele, bei denen diese neue Sprachfunktion nützlich ist?
decltype(auto)
für etwas Ähnliches verwendettemplate<class U, V> decltype(auto) first(std::pair<U, V>& p) { return p.first; }
, obwohl mir dann klar wurde, dass ich etwas verwenden musste,return (p.first);
was überraschenderweise funktioniert (aber IIRC ist dies sogar beabsichtigt).decltype(auto)
etwas entgegen den Erwartungen in das deklarierte Objekt kopiert / verschoben werden kann.Antworten:
Rückgabetypweiterleitung im generischen Code
Für nicht generischen Code, wie das erste Beispiel, das Sie angegeben haben, können Sie manuell auswählen, um eine Referenz als Rückgabetyp zu erhalten:
Im generischen Code möchten Sie jedoch in der Lage sein, einen Rückgabetyp perfekt weiterzuleiten, ohne zu wissen, ob es sich um eine Referenz oder einen Wert handelt.
decltype(auto)
gibt Ihnen diese Fähigkeit:Verzögern des Rückzugs vom Rückgabetyp in rekursiven Vorlagen
In diesen Fragen und Antworten vor einigen Tagen wurde während der Vorlageninstanziierung eine unendliche Rekursion festgestellt, wenn der Rückgabetyp der Vorlage als
decltype(iter(Int<i-1>{}))
anstelle von angegeben wurdedecltype(auto)
.decltype(auto)
wird hier verwendet, um den Abzug des Rückgabetyps zu verzögern, nachdem sich der Staub der Schabloneninstanziierung gelegt hat.Andere Verwendungen
Sie können auch
decltype(auto)
in anderen Kontexten verwenden, z. B. im Entwurf des Standards N3936 auch Staaten7.1.6.4 Auto Speci fi er [dcl.spec.auto]
Der Entwurf enthält auch dieses Beispiel für die Variableninitialisierung:
quelle
(i)
vsi
eine neue Sache in C ++ 14?decltype(expr)
unddecltype((expr))
unterscheiden sich bereits in C ++ 11, dies verallgemeinert dieses Verhalten.auto
die Arbeit genauso gut erledigt, da das Ergebnis ohnehin nach Wert zurückgegeben wird ... Oder habe ich es verpasst etwas?Zitate von hier :
decltype(auto)
Dies ist in erster Linie nützlich, um den Rückgabetyp von Weiterleitungsfunktionen und ähnlichen Wrappern abzuleiten , bei denen der Typ einen von Ihnen aufgerufenen Ausdruck genau „verfolgen“ soll.Zum Beispiel mit den folgenden Funktionen:
Es
decltype(auto)
ist jedoch nicht beabsichtigt, darüber hinaus ein weit verbreitetes Merkmal zu sein.Insbesondere, obwohl es zum Deklarieren lokaler Variablen verwendet werden kann, ist dies wahrscheinlich nur ein Gegenmuster, da die Referenz einer lokalen Variablen nicht vom Initialisierungsausdruck abhängen sollte.
Es hängt auch davon ab, wie Sie die return-Anweisung schreiben.
Die beiden folgenden Funktionen haben beispielsweise unterschiedliche Rückgabetypen:
string
, die zweite gibt zurückstring&
, was eine Referenz auf die lokale Variable iststr
.Aus dem Vorschlag können Sie weitere Verwendungszwecke ersehen.
quelle
auto
für die Rücksendung verwenden?auto
Rückgabe) arbeiten, aber das OP hat speziell nach Verwendungen von gefragtdecltype(auto)
.auto lookup_a_string() { ... }
? Ist es immer ein Nichtreferenztyp? Und muss daherauto lookup_a_string() ->decltype(auto) { ... }
erzwungen werden, dass Referenzen (in einigen Fällen) zurückgegeben werden können?auto
wird als Übergabe-Wert-Vorlage definiert, daher kann es sich nicht um eine Referenz handeln. Bitte warten,auto
kann natürlich alles sein, einschließlich einer Referenz.std::vector
. Sagen Sie, Sie habentemplate<typename T> struct S { auto & operator[](std::size_t i) { return v[i]; } std::vector<T> v; }
. DannS<bool>::operator[]
wird aufgrund der Spezialisierung von eine baumelnde Referenz zurückgegebenstd::vector<bool>
. Durch Ändern des Rückgabetyps,decltype(auto)
um dieses Problem zu umgehen.