Frage

hatte ich angenommen, dass die kanonische Form für Operator +, die Existenz einer überladenen Operators + = Member-Funktion unter der Annahme, wie das war:

const T operator+(const T& lhs, const T& rhs)
{
    return T(lhs) +=rhs;
}

Aber es wurde mir darauf hingewiesen, dass dies würde auch funktionieren:

const T operator+ (T lhs, const T& rhs)
{
    return lhs+=rhs;
}

Im Wesentlichen ist diese Form Transfer Erstellung der temporären aus dem Körper der Implementierung des Funktionsaufruf.

Es scheint ein wenig umständlich verschiedene Typen für die beiden Parameter zu haben, aber ist es etwas falsch mit der zweiten Form? Gibt es einen Grund einen über den anderen zu bevorzugen?

War es hilfreich?

Lösung

Mit der editierte Frage, die erste Form wäre vorzuziehen. Der Compiler wird eher den Rückgabewert optimieren (man könnte dies überprüfen, indem Sie einen Haltepunkt in dem Konstruktor für T platzieren). Die erste Form nimmt auch beiden Parameter als const, was wünschenswerter wäre.

Forschung zum Thema Rückgabewert Optimierung , wie diese Verbindung als kleines Beispiel: http://www.cs.cmu.edu/~gilpin/c++/performance.html

Andere Tipps

Ich bin nicht sicher, ob es viel Unterschied in den generierten Code für entweder.

Zwischen diesen beiden, würde ich (persönlich) bevorzuge die erste Form, da es besser, die Absicht vermittelt. Dies ist sowohl in Bezug auf Ihre Wiederverwendung des Operators + = und das Idiom von templatized Typen von const vorbei &.

Ich würde die erste Form zum besseren Lesbarkeit bevorzugen.

Ich hatte zweimal zu überlegen, bevor ich sah, dass der erste Parameter in kopiert wurde. Ich war nicht erwartet. Deshalb, da beide Versionen wahrscheinlich genauso effizient sind, würde ich ihnen eine auswählen, die leichter zu lesen ist.

const T operator+(const T& lhs, const T& rhs)
{
    return T(lhs)+=rhs;
}

, warum das nicht, wenn Sie die Prägnanz wollen?

Mein erster Gedanke ist, dass die zweite Version infinitessimally schneller sein könnte als die ersten, weil kein Hinweis auf dem Stapel als Argument geschoben wird. Dies würde jedoch sehr Compiler abhängig sein und hängt zum Beispiel ab, ob der Compiler führt Named Rückgabewert Optimierung oder nicht.

Wie auch immer, im Zweifelsfall wählen Sie nie für eine sehr kleine Leistungssteigerung, die nicht einmal existieren könnte und Sie mehr als wahrscheinlich nicht brauchen -. Wählen die klarste Version, die die erste ist

Eigentlich ist der zweite bevorzugt. Wie in dem C ++ Standard angegeben,

  

3.7.2 / 2: Automatische Lagerdauer

     

Wenn ein benannte automatisches Objekt   Initialisierung oder ein destructor mit   Nebenwirkungen, wird es nicht sein,   zerstört vor dem Ende seines Blockes,   noch soll sie als beseitigt werden   Optimierung, auch wenn es zu sein scheint   ungebraucht, außer dass ein Klassenobjekt oder   seine Kopie als beseitigt werden   angegeben in 12,8.

Das heißt, da ein unbenannte temporäres Objekt erstellt wird eine Kopie Konstruktor, der Compiler nicht den Rückgabewert Optimierung verwenden. Für den zweiten Fall jedoch wird die ungenannte Rückgabewert Optimierung erlaubt. Rückgabewert Optimierung namens Beachten Sie, dass, wenn Ihr Compiler implementiert, der beste Code

const T operator+(const T& lhs, const T& rhs)
{
    T temp(lhs);
    temp +=rhs;
    return temp;
}

Ich glaube, wenn man sie inlined beide (ich würde da sie nur Funktionen Spedition und vermutlich der Operator + = () Funktion ist out-of-line), können Sie in der Nähe nicht zu unterscheiden Codegenerierung bekommen würde. Das heißt, das erste weitere kanonische ist. Die zweite Version ist unnötig "cute".

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top