Frage

Bitte beachten Sie die drei Funktionen.

std::string get_a_string()
{
    return "hello";
}

std::string get_a_string1()
{
    return std::string("hello");
}

std::string get_a_string2()
{
    std::string str("hello");
    return str;
}
  1. Will RVO in allen drei Fällen angewendet werden?
  2. Ist es OK, um eine temporäre wie im obigen Code zurückzukehren? Ich glaube, dass es in Ordnung ist, da ich es eher nach Wert zurückkehre als Rückkehr eines Hinweises auf mich.

Alle Gedanken?

War es hilfreich?

Lösung

In zwei ersten Fällen RVO Optimierung stattfinden wird. RVO ist alt-Funktion und die meisten Compiler unterstützt. Der letzte Fall ist so NRVO (Named RVO) genannt. Das ist relativ neue Funktion von C ++. Standard erlaubt, aber keine Umsetzung von NRVO erfordern (wie auch RVO), aber einige Compiler unterstützt.

Sie können mehr über RVO in Artikel 20 von Scott Meyers Buch lesen More Effective C ++. 35 Neue Wege, um Ihre Programme zu verbessern und Design .

Hier ist ein guter Artikel über NRVO in Visual C ++ 2005.

Andere Tipps

Erstens ist es völlig in Ordnung, eine vorübergehende Rückkehr nach Wert das ist, was Sie tun. Es wird kopiert und wenn die ursprünglichen die Kopie Umfang hinausgehen wird nicht tun, und sicher durch den Anrufer verwendet werden kann.

Zweitens alle drei Fälle sind in der Tat identisch (da Sie im dritten Fall nicht die temporären Zugriff sowieso) und ein Compiler könnte sogar den gleichen Code für alle von ihnen emittieren. Daher kann es RVO verwendet in allen drei Fällen. Dies ist völlig Compiler abhängig.

sind alle Fälle richtig. Sie alle werden eine temporäre Konstruktion und den Kopierkonstruktor des Rückgabetyps gelten. Notwendigerweise, wenn es kein Copykonstruktor ist, wird der Code nicht.

RVO wird alle drei Fälle unter den meisten Compiler geschehen auf. Der einzige Unterschied ist der letzte in denen die es nicht erzwingen. Dies, weil Sie eine benannte Variable haben. Aber die meisten Compiler sind intelligent genug, um RVO noch darauf anzuwenden ... die später die genannte Variable deklariert wird und die weniger Transformationen es angewendet wird, um die besseren Chancen für RVO auf eine benannte Variable angewendet werden.

Im Übrigen einen Verweis Rückkehr ist natürlich möglich, wie Sie in anderen Code gesehen haben könnte. Was müssen Sie nicht tun, ist eine Referenz t ein lokales Objekt zurück.

std::string& get_a_string2()
{
    std::string str("hello");
    return str; //error!
}

Wird eine Kompilierung Fehler produzieren, wie Sie wissen. Allerdings

std::string& get_a_string2(std::string& str)
{
    // do something to str
    return str; //OK
}

Wird gut funktionieren. Auf diesem Fall gibt es keinen Bau- oder Kopie Bau beteiligt. Einfach die Funktion einen Verweis auf ihr Argument zurück.

  1. Es hängt von Ihrem Compiler - was Plattform sind Sie beziehen? Die beste Weg, um herauszufinden, ist ein sehr zu kompilieren kleines Test-App und überprüfen Sie die ASM Compiler erzeugt.

  2. Ja, es ist in Ordnung, obwohl Sie nie erwähnen, was Sie besorgt über; Geschwindigkeit? Stil? Sie können eine lokal auf eine konstante Referenz vorübergehend - die Lebensdauer der temporären wird auf die Lebensdauer der Referenz verlängert werden - versuchen Sie es und sehen Sie selbst! (Herb Sutter exaplins dieses

scroll top