2012-04-20 8 views
5

Escribí el siguiente código para entender la semántica de movimiento. Funciona como se esperaba (es decir, sin copias y solo se mueve) en g ++ - 4.6 pero no en g ++ - 4.7.0. Pensé que es un error al enlazar en g ++ - 4.7.0 pero este link dice que no es un error en g ++ - 4.7. Entonces, como lo entendí por el enlace de arriba, hice el movimiento del constructor de movimiento pero aún así solo hace copias. Sin embargo, si hago que el constructor de copia no tenga sentido, solo los movimientos toman lugar. ¿Alguien puede explicar esto?vector, semántica de movimiento, nothrow y 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; 
} 

Respuesta

5

¿Cómo está usted "hacer el movimiento de constructor nothrow"? Con g ++ 4.7, si anoto el constructor de movimiento con noexcept, entonces su ejemplo solo se mueve:

S(S&& x) noexcept{ ... } 

no of moves = 25 
no of copies = 0 
+0

Gracias. Lo escribí como 'S (nothrow) (S && ​​x) {....}'. Pero entonces, ¿cuál es la diferencia entre estas dos versiones "nothrow"? – suresh

+1

'noexcept' es la palabra clave C++ 11 para marcar algo como no tirar. La firma que ha usado declara una función llamada 'nothrow' que toma' S' por rvalue ref y devuelve 'S' por valor. –

+0

Eso explica por qué marcar el constructor de copia de esta manera hace que g ++ 4.7 use el constructor de movimientos: su clase ya no ** tiene ** un constructor de copia (sino una función llamada 'nothrow'), ya que g ++ 4.7 sigue al 'don' t implícitamente genera un constructor de copia si hay una regla de "move constructor", por lo que 'std :: vector' tiene que usar el constructor de movimientos. –

Cuestiones relacionadas