2010-11-05 7 views

Respuesta

7

swap() toma una referencia no const a un vector<int>. Una referencia no const no puede vincularse a un valor r (un objeto temporal). Una llamada a una función que devuelve por valor (como f) es un valor r.

La razón de que f(x).swap(v) funciona es porque dentro de std::vector<int>::swap, el objeto temporal devuelto por f(x) puede utilizar this para referirse a sí mismo. this no es un valor r.

+0

¿Por qué 'la referencia no constante no puede vincularse a un valor_r'? – yoyo

+4

@yoyo: Esto se explica en [¿Por qué una referencia no constante no puede enlazarse a un objeto temporal?] (Http://stackoverflow.com/questions/1565600/how-come-a-non-const-reference-cannot -bind-to-a-temporary-object) (especialmente la respuesta de sbi) –

+0

Personalmente, considero que es una decisión muy incómoda en un lenguaje donde todo lo demás depende del programador. Me divierte un poco que la semántica de "movimiento" y las referencias "destructivas" asociadas permitan algo similar. –

1

Puede llamar a funciones miembro en temporarios, pero en C++ no pueden vincularse a referencias no constantes.

Por ejemplo:.

int &x = 5; // illegal because temporary int(5) cannot be bound to non-const reference x 
+0

En este caso, está claro que no puede unir 'x' al resultado de la evaluación de' 5', porque la evaluación de '5' arroja el valor 5 de tipo' int', por lo que no tendría ningún objeto de tipo 'int' para enlazar. IOW, aquí hay ** no temporal ** 'int (5)'. – curiousguy

+0

@ curiousguy: ¿Lo mismo de nuevo? No crea un temporal? ¿Por qué 'int const & x = 5' funciona? – Nawaz

+0

@Nawaz funciona porque se crea un temporal. – curiousguy

1

En realidad, (mientras James' answer está en lo cierto (y también lo es Prasoon's), hay algún problema subyacente de captar

Cuando reducimos f(x) a su resultado y, y y.swap(v) (o v.swap(y), no importa en este caso) para usar nombres de identificador generalizados, se convierte en

y.func(v) 

Ahora, func() ser una función miembro con un argumento, que en realidad tiene dos argumentos: lo que se ha pasado como v y lo implícito this puntero cada función miembro no estática recibe, aquí cota a y. Al echar a un lado la encapsulación, cada función miembro llamada como y.func(v) podría convertirse en una función no miembro para llamarse como func(y,v). (Y de hecho, en realidad hay funciones no miembro swap(). Además, cada vez que necesite sobrecargar uno de esos operadores binarios que podrían estar sobrecargados como miembros o no miembros, debe tomar esta decisión).

Sin embargo, existen diferencias sutiles entre y.func(v) y func(y,v), debido a que C++ trata el argumento this, el argumento que se pasa por escrito antes de que el . (el punto), diferente de los otros argumentos, y lo hace de muchas maneras .
Como has descubierto, el argumento this podría ser un valor de lado derecho (temporal) incluso para const funciones no miembros, mientras que para los otros argumentos, una referencia no constante evita rvalues ​​quede vinculado a la discusión.Además, es el argumento thistipo en tiempo de ejecución podría influir en qué función se llama (para virtual miembros), mientras que los otros argumentos de tipo en tiempo de ejecución es irrelevante, porque se elige una función sólo en función de su tipo en tiempo de compilación solamente. Y las conversiones implícitas solo se aplican a los argumentos explícitos de las funciones miembro, pero nunca a su argumento implícito this. (Es por eso que puede pasar una cadena literal para un const std::string&, pero no se puede llamar std::string::size() en una cadena literal.)

lo tanto, para concluir, a pesar del hecho de que lo que está antes de la . termina como un argumento de función (implícita), en realidad es tratado de manera muy diferente de los otros argumentos de la función.

+0

¿Cómo puede reducir 'f (x) .swap (v) 'to' xf (y) '? No entiendo esta parte ... – yoyo

+0

@yoyo: puedo ver que es difícil de entender, ya que mi elección de los nombres de las variables fue pobre. Me disculpo. Cambié los nombres, espero que ahora sea más fácil de entender. – sbi

Cuestiones relacionadas