2010-02-07 13 views
9

Si una función devuelve un int, ¿puede asignarse mediante un valor int? No veo que tenga demasiado sentido asignarle un valor a una función.Si a funciones devuelven un int, ¿se le puede asignar un int?

int f() {} 

f() = 1; 

Me di cuenta de que, si la función devuelve una referencia a un int, está bien. ¿Está restringido solo a int? ¿Qué hay de otros tipos? o alguna otra regla?

int& f() {} 

f() = 1; 
+1

¿cuál sería el objetivo de asignar un valor a una función? ¿Por qué no usar una variable en su lugar? –

Respuesta

22

La primera función devuelve un valor por entero, que es valor r. No se puede asignar a un valor r en general. El segundo f() devuelve una referencia a un entero, que es un valor l, por lo que puede asignarlo.

int a = 4, b = 5; 

int& f() {return a;} 

... 
f() = 6; 
// a is 6 now 

Nota: no asigna un valor a la función, solo asigne a su valor de retorno. Tenga cuidado con lo siguiente:

int& f() { int a = 4; return a; } 

usted está volviendo una referencia a un temporal, que ya no es válida después se devuelve la función. El acceso a la referencia invoca un comportamiento indefinido.

+0

, podría explicar por qué el valor por valor de retorno es un valor r? – skydoor

+0

El valor de retorno de una función no es una variable de C++ adecuada, como 'int i;'. Es solo un valor temporal. No representa una ubicación de memoria. –

+1

@skydoor, se puede resumir por * "solo se puede asignar a objetos" *. En su llamada, la función devuelve un valor que no se corresponde con un objeto: el número entero representa * solo * un valor abstracto.Si, por ejemplo, hubiera devuelto un 'std :: string', el valor devuelto (que en realidad es un valor r) corresponderá a un objeto de cadena, y usted * podría * asignarlo. Lo mismo es cierto para un valor de retorno 'int &'. En ese caso, el "valor" devuelto (que es un valor l) corresponde a un int * object *, y usted puede asignarlo. Un objeto es necesario, porque una asignación modifica un estado almacenado. –

1

No es limitado a int solamente, pero para los tipos primitivos no tiene sentido hacerlo. Es útil cuando tiene sus clases

+1

¿Está diciendo que no tiene sentido devolver una referencia a un tipo primitivo? Entonces, cosas como 'operator []' of 'vector ' no tienen sentido? – sepp2k

+1

Tiene mucho sentido hacerlo (si con 'it' quiere decir devolver una referencia) - si tiene un std :: vector , entonces las funciones que acceden a cosas en el vector devuelven int referencias. –

+0

En el contexto de su ejemplo – anthares

0

Si una función devuelve un objeto por valor, entonces la asignación es posible, a pesar de que la llamada de función es un rvalue Por ejemplo:

std::string("hello") = "world"; 

Esto crea un objeto de cadena temporal, lo muta y luego lo destruye inmediatamente. Un ejemplo más práctico es:

some_function(++list.begin()); 

No podría escribir list.begin() + 1, porque además no es posible en los iteradores de la lista, pero la subasta está bien. Este ejemplo no implica la asignación, pero la asignación es solo un caso especial de la regla más general "se pueden invocar funciones miembro sobre valores r".

+0

¿Es un caso común? ¿Puedes darme un ejemplo? – skydoor

+1

Aunque entiendo que es solo un ejemplo, observe que '++ list.begin()' no es necesario para funcionar. El operador puede implementarse como una función libre que acepta una referencia no constante y no se vinculará al iterador temporal. –

+1

Gracias, nunca recuerdo qué operadores tienen funciones miembro y cuáles pueden ser funciones gratuitas. – fredoverflow

Cuestiones relacionadas