2012-04-20 7 views
5

Ich schrieb den folgenden Code, um Bewegungssemantik zu verstehen. Es funktioniert wie erwartet (dh keine Kopien und bewegt sich nur) in g ++ - 4.6, aber nicht in g ++ - 4.7.0. Ich dachte, das ist ein Fehler beim Verknüpfen in g ++ - 4.7.0, aber dieses link sagt, dass es kein Fehler in g ++ - 4.7 ist. So, wie ich aus dem obigen Link verstehe, habe ich den Move-Konstruktor not throw gemacht, aber es kopiert nur noch. Wenn ich jedoch den Kopierkonstruktor not-throw mache, finden nur Verschiebungen statt. Kann das jemand erklären?Vektor, move Semantik, Nothrow und g ++ 4.7

#include <iostream> 
#include <vector> 
using namespace std; 

struct S{ 
int v; 
static int ccount, mcount; 
S(){} 
    //no throw constructor 
    //S(nothrow)(const S & x){ 
S(const S & x){ 
    v = x.v; 
    S::ccount++; 
} 
S(S&& x){ 
    v = x.v; 
    S::mcount++; 
} 
}; 

int S::ccount = 0; 
int S::mcount = 0; 
int main(){ 

vector<S> v; 
S s; 

for(int i = 0; i < 10; i++) { 
    v.push_back(std::move(s)); 
} 

cout << "no of moves = " << s.mcount << endl; 
cout << "no of copies = " << s.ccount << endl; 
return 0; 
} 

Antwort

5

Wie machen Sie "den Move Constructor nothrow"? Mit g ++ 4.7, wenn ich den Move-Konstruktor mit noexcept annotieren, dann bewegt sich Ihr Beispiel nur:

+0

Danke. Ich schrieb es als 'S (nothrow) (S && ​​x) {....}'. Aber was ist der Unterschied zwischen diesen beiden "nothrow" Versionen? – suresh

+1

'noexcept' ist das C++ 11-Schlüsselwort zum Markieren von etwas als nicht-werfen. Die von Ihnen verwendete Signatur deklariert eine Funktion namens 'nothrow', die ein' S' von rvalue ref akzeptiert und einen 'S' nach Wert zurückgibt. –

+0

Das erklärt, warum g ++ 4.7 den Move-Konstruktor benutzt, um den Kopierkonstruktor zu markieren: Ihre Klasse hat nicht mehr ** einen Kopierkonstruktor (sondern stattdessen eine Funktion namens "nothrow"), da g ++ 4.7 dem "don" folgt t Implizit wird ein Kopierkonstruktor generiert, wenn es einen Move-Konstruktor "rule" gibt, also muss 'std :: vector' den Move-Konstruktor verwenden. –