2012-01-15 16 views
8

código va a continuación:vector <T> :: swap y objeto temporal

#include <vector> 

int main() 
{ 
    vector<int> v1(5,1); 
    v1.swap(vector<int>()); //try to swap v1 with a temporary vector object 
} 

El código anterior no se puede compilar, error:

error: no matching function for call to ‘std::vector<int, std::allocator<int> >::swap(std::vector<int, std::allocator<int> >)’ 

Pero, si cambio el código para algo como esto, puede compilar:

int main() 
{ 
    vector<int> v1(5,1); 
    vector<int>().swap(v1); 
} 

¿Por qué?

Respuesta

9

Porque vector<int>() es rvalue (un temporal, aproximadamente), y no puede enlazar una referencia que no sea const a un valor r. Entonces, en este caso, no puede pasarlo a una función tomando una referencia que no sea const.

Sin embargo, está perfectamente bien para invocar funciones miembro en temporales, por lo que su segundo ejemplo se compila.

+0

¿Podría por favor ofrecer más información sobre "' vector () 'is an rvalue"? 'rvalue' debería aparecer en el lado derecho de' = ', ¿verdad? – Alcott

+0

@Alcott: es más general que eso. Ver http://en.wikipedia.org/wiki/Value_(computer_science). –

+0

Encontré este artículo muy útil para entender los valores r: http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++.html – Adam

6

La llamada v1.swap(std::vector<int>()) intenta vincular una referencia temporal (es decir, std::vector<int>()) a una referencia no constante. Esto es ilegal y falla. Por otro lado, usar std::vector<int>().swap(v1) llama a una función no const en el [no const] temporal que está permitido.

En C++ 2011, habría pensado que la declaración sería cambiado a std::vector<T>::swap(T&&) y se convertiría así en Aceptar para utilizar swap() con los temporales (pero, obviamente, todavía no const con objetos). Como GMan señaló que este no es el caso.

+1

No, solo 'swap (T &) '. – GManNickG