2014-07-24 5 views
6

Jemand hat mir vorgeschlagen, dass ein Optimierer parameter-passing-by-const-reference und parameter-passing-by-value in jeder Funktion, die dies nicht tut, frei vertauschen darf Ändern Sie den Parameter. Ist das nach dem C++ - Standard erlaubt?Ist ein Aufruf des Kopierkonstruktors garantiert, wenn Argument nach Wert übergeben wird

Oder anders, im Code angegeben

struct MyClass { 
    MyClass(MyClass const& mc) { std::cout << "xxx" << std::endl; } 
}; 

void foo(MyClass mc) { } 

MyClass mc; 
foo(mc); 

ist die C++ Standard Garantie dafür, dass "xxx" wird immer gedruckt? (Referenz auf Standard geschätzt)

+0

Der Compiler kann beliebigen Code generieren, der sich entsprechend dem Code verhält. Es kann nicht magisch etwas wie das Drucken Ihrer Nachricht auslassen, es sei denn, es gibt eine ausdrückliche Erlaubnis dafür (und das passiert nur in einem Fall, der Kopie Elision ist, und die für Ihre Situation nicht gilt). –

+0

Es sei denn, es ist ein einfacher Datentyp oder Ihre Funktion wird wahrscheinlich den Wert im Inneren ändern, ich würde immer const ref als "default" übergeben. Das ist nur meine persönliche Meinung. –

Antwort

8

Ja, der Kopierkonstruktor wird hier verwendet. Kopieren elision ist nur unter bestimmten Umständen erlaubt, angegeben von C++ 11 12.8/31:

  • in einer return Aussage ...
  • in einem throw-Ausdruck ...
  • , wenn ein temporäre Klassenobjekt ... würde kopiert/verschoben werden ...
  • wenn die Ausnahme Deklaration einer Exception-Handler ... als Ausnahmeobjekt
ein Objekt des gleichen Typs erklärt

Nichts davon gilt hier, obwohl die dritten anzuwenden wäre, wenn Sie einen temporären Wert übergeben:

foo(MyClass()); 

In diesem Fall wird die Nachricht nicht gedruckt werden kann.

Wenn der Copy-Konstruktor keine Nebenwirkungen hatte, dann könnte die Kopie in jedem Fall unter der "als-ob" -Regel verschwinden (ob das Argument eine temporäre war oder nicht), da dies keine Auswirkungen auf die Programm das sichtbare Verhalten.

+0

Meinst du das in 'foo (MyClass());' der Compiler muss die Nachricht nicht drucken? Dann wäre die if-Klausel in Ihrem letzten Satz irreführend. So verstehe ich wenigstens Punkt 3. –

+0

@ TobiasBrüll: Ja, wenn das Argument ein temporäres Argument ist, dann gilt Punkt 3, daher wird die Nachricht möglicherweise nicht gedruckt. Der letzte Satz würde in jedem Fall gelten, wenn es keine Nebenwirkungen gegeben hätte (aber nicht, wenn es, wie in Ihrem Beispiel, gibt); Entschuldigung, wenn Sie es irreführend fanden, werde ich versuchen, einen besseren Weg zu finden, es zu formulieren. –

Verwandte Themen