2017-04-02 3 views
6

ich std::for_each hier http://en.cppreference.com/w/cpp/algorithm/for_each in die Dokumentation lese und sah, dass der Rückgabewert std::move(f) istWarum for_each Funktion zurückkehren, indem Sie bewegen

Warum der Standard der Eingangsparameter im Rückgabewert bewegt erzwingt? Wird es sowieso nicht standardmäßig verschoben, da der Eingabeparameter als Wert übergeben wird?


Dies führt mich zu einem paar followups, wenn Sie kompilieren den folgenden Code

Something function(Something something) { 
    return something; 
} 
  1. Die return-Anweisung ist ein Schritt auf meinem System mit der höchsten Optimierungsstufe (-O3), Warum geben die meisten Compiler diesen Rückgabewert nicht an? Lokale Werte sind nicht vorhanden, aber Funktionsargumente sind nicht vorhanden.

  2. Erzwingt C++ 17 Elision in diesem Fall? Ich lese den Vorschlag (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html), aber ich verstehe nicht vollständig, welche Fälle für die obligatorische Elision qualifizieren.

Ich habe schon versucht, diese auf Apple LLVM version 8.0.0 (clang-800.0.42.1) auf meinem Mac und auf g++ 5.4 auf Ubuntu 16.04.

Antwort

11

Dies ist aufgrund einer späten Änderung der Bewegungssemantik Regeln für C++ 11. The original move proposal wurde nicht automatisch verschoben, wenn By-Value-Funktionsargumente in der Rückkehrklausel angezeigt wurden. Spät in C++ 11 wurde dieses Sprachenfeature jedoch hinzugefügt.

Vor dem Hinzufügen der Sprachfunktion wurde for_each "wurde verschoben". Zu dieser Zeit war die Bewegung auf der Rückkehrerklärung notwendig. Aber es wurde überflüssig, obwohl es bis zur Auslieferung von C++ 11 harmlos war.

LWG issue 2747 korrigiert dies für C++ 17.

Was Ihre erste Folgefrage betrifft, bin ich kein Compiler-Schreiber, aber meine beste Vermutung ist: Es ist derzeit nicht legal, die Rückkehr von einem Funktionsparameter (so viel ich weiß), und ich rate als Warum es nicht legal ist, ist, dass niemand herausgefunden hat, wie man es umsetzt, und daher hat niemand die Motivation gehabt, den Standard zu ändern, um ihn legal zu machen.

Zweite Follow-up: Nein, C++ 17 erzwingt Elision in diesem Fall nicht. Die Regeln bleiben in diesem Fall dieselben wie für C++ 11, abgesehen davon, dass der redundante Wechsel von for_each nicht mehr spezifiziert ist.

Aus den Kommentaren unten:

Warum sagen Sie es nicht legal ist die Rückkehr von einem Funktionsparameter elide?

Ich Referenzierung N4660, die C++ 17 ist, aber es gibt eine ähnliche Formulierung in C++ 98/03/11/14 ... Backup wurde vor kurzem geschützt. Siehe N4659 statt (genauso gut):

15.8.3 Elision kopieren/verschieben [class.copy.elision]

  1. Wenn bestimmte Kriterien erfüllt sind, wird eine Implementierung erlaubt das Kopieren/Verschieben Bau eines Klassenobjekt wegzuzulassen, ...

    • in einer return-Anweisung in einer Funktion mit einem Klassenrückgabetyp, wenn der Ausdruck Ausdruck der Name eines nichtflüchtigen automatischen Objekts ist (mit Ausnahme eines Funktionsparameters oder einer Variablen, die durch die Ausnahmeklaration eines handl eingeführt wird er (18,3)) mit dem gleichen Typ (cv-Qualifikation) als Funktion Rückgabetyp ignoriert, kann das Kopieren/Verschieben Vorgang durch Aufbau der automatischen Objekt direkt in den Rücklauf des Funktionsaufrufobjekt weggelassen werden

Diese Sprache verbietet ausdrücklich Elision von Funktionsparametern.

+0

Warum sagen Sie, dass es nicht legal ist, die Rückgabe von einem Funktionsparameter zu verhindern? Die Art, wie ich es sehe, Funktionsparameter sind die gleichen wie lokale Variablen, außer dass die Reihenfolge der Konstruktion und der Zerstörung nicht spezifiziert ist. – Curious

+0

@Curious: Mit einem Zitat aus C++ 17 aktualisiert, um dies zu adressieren. –

+0

Eine letzte Sache. Warum hat der Vorschlag Elision von Funktionsargumenten ausgeschlossen? Ich versuche nur die Gründe für die Entscheidung zu verstehen. – Curious

Verwandte Themen