Disponible la nueva versión "donationware" 7.3 de OrganiZATOR
Descubre un nuevo concepto en el manejo de la información.
La mejor ayuda para sobrevivir en la moderna jungla de datos la tienes aquí.

Curso C++

[Home]  [Inicio]  [Índice]


4.13.7  Asignación a funciones

§1  Sinopsis

Hemos señalado repetidamente que los valores devueltos por funciones no son direccionables porque son variables de registro ( 4.4.7).  Además por lo general, salvo cuando devuelven una referencia, tampoco son asignables porque no constituyen Lvalues.  Por esta razón, es normal ver las invocaciones de funciones aisladas, o a la derecha de expresiones de asignación, cuando se utilizan para asignar a una variable el valor devuelto por la función.  Son expresiones del tipo:

func1(x);

y = func2();

Sin embargo, cuando el valor devuelto es un Lvalue, pueden ser asignadas directamente.  En estos casos el compilador crea un objeto temporal adecuado.  Es el caso del ejemplo que sigue:

int& foo(int& x) { ++x; return x; }

int main() {
   int x = 3;
   cout << foo(x);    // -> 4
   ++foo(x);
   cout << x;         // -> 6

   ...

}


§2  Si el valor devuelto es un puntero a miembro, entonces también es posible realizar asignaciones utilizando la invocación de la función:

struct E {
   int x;
   int* func() { return &x; }
};

int main() {
   E e1 = {1};
   cout << e1.x;    // -> 1
   *e1.func() = 2;
   cout << e1.x;    // -> 2

   ++*e1.func();
   cout << e1.x;    // -> 3
   ...

}

§3  También es posible realizar asignaciones a la invocación de la función si esta devuelve una referencia:

struct E {
   int x;
   int& func() { return x; }
};

int main() {
   E e1 = {1};
   cout << e1.x;    // -> 1
   e1.foo() = 10;
   cout << e1.x;    // -> 10
   ++e1.foo();
   cout << e1.x;    // -> 11

   ...

}

§4  Otro caso similar al anterior, utilizando una función externa en lugar de un método:

struct E {
   int x;
};
int& foo(E& e) { return e.x; }

int main() {
   E e1 = {1};
   cout << e1.x;    // -> 1
   foo(e1) = 20 ;
   cout << e1.x;    // -> 20
   ++foo(e1);
   cout << e1.x;    // -> 21

   ...

}

§5  También son válidas las asignaciones cuando se devuelve un puntero al objeto:

struct E { int x; };

E* newObject() {
   E* eptr = new E;
   return eptr;
}

int main() {
   newObject()->x = 22;    // Ok. asignación permitida
   ...

}