Wann sollte ich den automatischen Rückgabetyp C ++ 14 verwenden?
Mit GCC 4.8.0 veröffentlicht, wir haben einen compiler unterstützt die automatische Rückgabetyp Abzug, Teil von C++14. Mit -std=c++1y
, ich kann dies tun:
auto foo() { //deduced to be int
return 5;
}
Meine Frage ist: Wann sollte ich diese Funktion nutzen? Wenn ist es nötig und Wann macht es code cleaner?
Szenario 1
Ersten Szenario, das ich denken kann ist, Wann immer möglich. Jede Funktion, die geschrieben werden können, auf diese Weise sein sollte. Das problem mit diesem ist, dass es vielleicht nicht immer machen den code lesbarer zu gestalten.
Szenario 2
Nächsten Szenario zu vermeiden, komplexere Typen zurückgegeben. Als ein sehr leichtes Beispiel:
template<typename T, typename U>
auto add(T t, U u) { //almost deduced as decltype(t + u): decltype(auto) would
return t + u;
}
Ich glaube nicht, dass jemals wirklich ein problem, aber ich denke, dass der Rückgabetyp explizit abhängig von den Parametern könnte klarer sein in einigen Fällen.
Szenario 3
Nächsten, zu verhindern Redundanz:
auto foo() {
std::vector<std::map<std::pair<int, double>, int>> ret;
//fill ret in with stuff
return ret;
}
In C++11, können wir manchmal nur return {5, 6, 7};
im Ort ein Vektor, aber das funktioniert nicht immer und wir müssen Sie die Art sowohl in der Funktion header und den Rumpf der Funktion. Dies ist rein überflüssig, und die automatische Rückgabetyp Abzug rettet uns vor, dass Redundanz.
Szenario 4
Schließlich, es kann verwendet werden, anstelle von sehr einfachen Funktionen:
auto position() {
return pos_;
}
auto area() {
return length_ * width_;
}
Manchmal, obwohl, betrachten wir die Funktion, wissen zu wollen, den genauen Typ, und wenn nicht, vorausgesetzt, wir haben zu gehen zu einem anderen Punkt im code, wie, wo pos_
deklariert ist.
Abschluss
Mit diesen Szenarien gelegt, welche von Ihnen tatsächlich beweisen, um eine situation, wo diese Funktion ist hilfreich bei der code-Reiniger? Was ist mit Szenarien, die ich versäumt haben, um Sie hier zu erwähnen? Welche Vorsichtsmaßnahmen sollte ich treffen, bevor Sie diese Funktion verwenden, so dass es nicht Biss mich später? Gibt es etwas neues in dieser Funktion bringt auf den Tisch, dass das nicht geht ohne es?
Beachten Sie, dass mehrere Fragen, die dazu gedacht sind, eine Hilfe bei der Suche nach Perspektiven, aus denen diese zu beantworten.
->decltype(t+u)
mit auto-Abzug tötet SFINAE. InformationsquelleAutor der Frage chris | 2013-04-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
C++11 stellen sich ähnliche Fragen: Wann Rückgabetyp Abzug in Lambda-Ausdrücke, und wenn zu verwenden
auto
Variablen.Die traditionelle Antwort auf die Frage in C und C++03 hat "across-Anweisung Grenzen, die wir machen, Typen explizit, innerhalb von Ausdrücken sind Sie in der Regel impliziten, aber wir können Sie mit expliziten casts". C++11 und C++1y einzuführen Typ Abzug Werkzeuge, so dass Sie verlassen kann sich die Art an neuen stellen.
Sorry, aber du wirst doch nicht, dies zu lösen, nach vorne, indem Sie die Allgemeinen Regeln. Sie müssen sich an bestimmten code, und selbst entscheiden, ob oder nicht es dient der Lesbarkeit angeben Arten alle über dem Platz: ist es besser für Ihren code, um zu sagen, "der Typ von diesem Ding ist X", oder ist es besser für Ihren code, um zu sagen, "der Typ von dieser Sache irrelevant ist für das Verständnis dieser Teil des Codes: der compiler muss wissen, und wir könnten wahrscheinlich Arbeit aus, aber wir brauchen nicht zu sagen, dass es hier"?
Da "Lesbarkeit" ist nicht Objektiv definiert[*], und außerdem variiert es von Leser, Sie haben eine Verantwortung als Autor/Herausgeber von einem Stück code, der sich nicht vollständig nachgekommen werden, indem ein style guide. Sogar soweit, dass ein style guide nicht festlegen, Normen, unterschiedliche Leute bevorzugen unterschiedliche Normen und wird dazu neigen, etwas zu finden, Fremd zu sein "weniger lesbar". Also die Lesbarkeit einer bestimmten vorgeschlagenen Stil-Regel kann oftmals nur beurteilt werden, die in Zusammenhang mit den anderen Stil-Regeln in Kraft.
Alle Ihre Szenarien (auch die erste) finden Verwendung für jemanden, der coding style. Persönlich finde ich die zweite werden die meisten überzeugende Anwendungsfall, aber auch so erwarte ich, dass es davon abhängen wird, Ihre Dokumentations-tools. Es ist nicht sehr hilfreich, um zu sehen, dokumentiert, dass der Rückgabetyp einer Funktion template ist
auto
, in der Erwägung, dass zu sehen es dokumentiert, wiedecltype(t+u)
schafft eine veröffentlichte Schnittstelle können Sie (hoffentlich) verlassen.[*] Gelegentlich jemand versucht, zu machen einige Objektive Messungen. Bis die kleinen soweit, dass jemand kommt mit einem statistisch signifikanten und allgemein anwendbaren Ergebnisse, Sie werden völlig ignoriert, durch die Arbeit der Programmierer, zugunsten des Autors Instinkte, was "lesbar".
InformationsquelleAutor der Antwort Steve Jessop
Allgemein gesprochen, die Funktion Rückgabetyp ist eine große Hilfe-Dokument eine Funktion. Die Benutzer werden wissen, was zu erwarten ist. Es gibt jedoch auch einen Fall, wo ich denke, es könnte nett sein, zu fallen, zurück geben, um Redundanz zu vermeiden. Hier ist ein Beispiel:
Diesem Beispiel ist entnommen aus der offiziellen Ausschuss Papier N3493. Der Zweck der Funktion
apply
ist es uns, die Elemente einerstd::tuple
Sie zu einer Funktion und zur Rückgabe des Ergebnisses. Dieint_seq
undmake_int_seq
sind nur ein Teil der Implementierung und wird wahrscheinlich nur verwirren Anwender, die versuchen zu verstehen, was es tut.Wie Sie sehen können, ist der Rückgabetyp ist nichts mehr als eine
decltype
des Ausdruck zurückgegeben. Darüber hinausapply_
nicht gemeint, gesehen zu werden von den Usern, ich bin nicht sicher, dass die Nützlichkeit der Dokumentation seiner Rückkehr geben, wenn es mehr oder weniger das gleiche wieapply
's ein. Ich denke, dass in diesem speziellen Fall fallen die return-Typ macht die Funktion mehr lesbar. Beachten Sie, dass diese sehr Rückgabetyp hat eigentlich schon fallen gelassen und ersetzt durchdecltype(auto)
im Vorschlag hinzufügenapply
standard, N3915 (beachten Sie auch, dass meine ursprüngliche Antwort, die älter als das Papier):Jedoch, die meisten der Zeit, ist es besser zu halten, zurück geben. In dem besonderen Fall, dass ich oben beschrieben habe, ist der Rückgabetyp ist eher unlesbar und potenzielle Nutzer nicht gewinnen alles, was es zu wissen. Eine gute Dokumentation mit Beispielen werden weit mehr nützlich.
Andere Sache, die nicht erwähnt wurden und doch: während
declype(t+u)
ermöglicht Ausdruck SFINAE,decltype(auto)
nicht (obwohl es ist ein Vorschlag, um dieses Verhalten ändern). Nehmen Sie zum Beispiel einefoobar
Funktion aufrufen, werden ein Typ istfoo
member-Funktion, wenn es vorhanden ist, oder Aufruf des Typsbar
member-Funktion, falls es vorhanden ist, und davon ausgehen, dass eine Klasse hat immer exactyfoo
oderbar
aber weder beides zugleich:Aufrufen
foobar
auf eine Instanz vonX
zeigtfoo
beim Aufruffoobar
auf eine Instanz vonY
zeigtbar
. Wenn Sie die automatische Rückgabetyp Abzug statt (mit oder ohnedecltype(auto)
), Sie erhalten nicht Ausdruck SFINAE und ruftfoobar
auf eine Instanz vonX
oderY
löst eine compile-time-Fehler.InformationsquelleAutor der Antwort Morwenn
Es hat nichts zu tun mit der Einfachheit der Funktion (nun-doppelte gelöscht dieser Frage soll).
Entweder die return-Typ festgelegt ist (nicht verwenden
auto
), oder abhängig in komplexer Weise auf einem template-parameter (verwenden Sieauto
in den meisten Fällen, gepaart mitdecltype
wenn es mehrere return-Punkte).InformationsquelleAutor der Antwort Ben Voigt
Es ist nie notwendig. Wann sollten Sie - Sie gehen zu bekommen eine Menge von verschiedenen Antworten zu. Ich würde sagen überhaupt nicht, bis Ihr tatsächlich ein akzeptierter Teil der standard-und gut unterstützt durch die Mehrheit der wichtigen Compiler der gleichen Weise.
Darüber hinaus, sein wird, ein religiöses argument. Ich würde persönlich sagen, noch nie - setzen in der tatsächlichen Rückgabetyp der code dadurch übersichtlicher, viel einfacher für die Wartung (kann ich eine Funktion, Unterschrift und wissen, was es gibt vs, tatsächlich mit, den code zu Lesen), und es entfällt die Möglichkeit, dass Sie denken, sollte es wieder einen geben und der compiler denkt, dass andere Probleme verursacht (so geschehen mit jeder Skript-Sprache, die ich je benutzt habe). Ich denke, dass auto war ein Riesen Fehler und es wird zu um Größenordnungen mehr Schmerzen als helfen. Andere sagen man soll es verwenden, die ganze Zeit, wie es passt Ihre Philosophie der Programmierung. Jedenfalls, das ist weit außerhalb des Gültigkeitsbereichs für diese Website.
InformationsquelleAutor der Antwort Gabe Sechan
Betrachten einer realen Produktionsumgebung: viele Funktionen und unit-tests in Abhängigkeit der Rückgabetyp
foo()
. Nehmen wir nun an, dass der Rückgabetyp ändern muss, warum auch immer.Wenn der Rückgabetyp ist
auto
überall, und die Anruferfoo()
- und Verwandte Funktionen verwendenauto
wenn immer der Wert zurückgegeben, werden die änderungen, die vorgenommen werden müssen, sind minimal. Wenn nicht, könnte dies bedeuten, Stunden extrem mühsame und fehleranfällige Arbeit.Als ein real-world Beispiel, ich wurde gebeten, dieses zu ändern ein Modul mit raw-Zeiger überall in der smart-Pointer. Die Befestigung der unit-tests war schmerzhafter als der eigentliche code.
Zwar gibt es andere Arten, wie das gehandhabt werden kann, die Verwendung von
auto
Gegenzug Arten scheint wie eine gute Passform.InformationsquelleAutor der Antwort Jim Wood
Möchte ich ein Beispiel geben, wo Rückgabetyp auto ist perfekt:
Vorstellen, die Sie erstellen möchten, einen kurzen alias für eine lange anschließende Aufruf der Funktion. Mit dem auto brauchen Sie nicht zu kümmern sich um die ursprünglichen Rückgabetyp (vielleicht wird es sich in Zukunft ändern), und die Benutzer können auf die ursprüngliche Funktion zu erhalten, die Reale Rendite, Typ:
PS: Hängt davon ab, diese Frage.
InformationsquelleAutor der Antwort kaiser