conociendo las rvalue references

17 views
Skip to first unread message

sole

unread,
Apr 11, 2012, 5:27:59 PM4/11/12
to cp...@googlegroups.com
Hola!!
Estuve leyendo sobre rvalue ref y sobre move y toda la movida de C++11&& :D (&& a propósito)
Y me dieron ganas de que comencemos un debate sobre:
- qué es rvalue ref
- qué implica un move y que pasa atrás del escenario
- otras cosas relacionadas que no se me ocurren ahora ;)
Y saquemos conclusiones sobre
- cuáles son las situaciones donde usar rvalue ref y move
- cuáles son las situaciones donde no usarl rvalue ref y move.

La idea es empezar de a poco para que todos los que se prendan al thread podamos entender de que se trata
y la idea también es usar a Fernando y Daniel para que nos aclaren los puntos oscuros!!
Esto significa que en este momento NADIE deberia colgarse con definiciones y conclusiones anticipadas vamos paso a paso!!!

Entonces por lo que vi en los diferentes foros deberiamos empezar con esta simple pregunta:
Qué es un rvalue y que es un lvalue?
Para ser más prácticos, en el siguiente ejemplo, qué lvalues y qué rvalues encuentran?

1. char c;
2. char * hola = "hola";
3. void fun( std::string s);
4. template<class T>
void fun2( T & arg);
5. const int i =1;
6. int j = i;
7. std::string holas = "hola";

Otros ejemplos?

Saludos,
 Sole



Fernando Pelliccioni

unread,
Apr 11, 2012, 5:38:25 PM4/11/12
to cp...@googlegroups.com


2012/4/11 sole <soledad...@gmail.com>
Buenas!

Recomiendo estos artículos...


Saludos,
FP.

 

sole

unread,
Apr 12, 2012, 9:44:12 AM4/12/12
to cp...@googlegroups.com
Hola Fernando,
Muchas gracias por el link! es el mismo que recomienda Scott Meyers en su libro the new C++ :D aca hay otro que tambien esta bueno http://thbecker.net/articles/rvalue_references/section_01.html (tambien recomendado por Meyers)

Alguien se suma a la idea de ir analizando este tema o ya lo saben todos o estan vagos?
Bss,
Sole


--
¿Eres miembro de "CyC++ Buenos Aires" verdad? Si no lo eres, has recibido este mesaje por error.
En caso de duda visita "http://groups.google.com/group/cppba"

Fernando Pelliccioni

unread,
Apr 12, 2012, 10:35:26 AM4/12/12
to cp...@googlegroups.com
Ah, mirá.
No pude leer el libro... tengo que "conseguirlo".
Esta muy buena la serie de artículos, incluso los comentarios, participa gente del comité e incluso de esos comentarios surgen cambios en los proposals.

Saludos,
FP.

2012/4/12 sole <soledad...@gmail.com>

Fernando Cacciola

unread,
Apr 12, 2012, 11:37:10 AM4/12/12
to cp...@googlegroups.com
Hola Sole,

Me parece genial lo que proponés (hace mucho que quiero hacerlo en la
lista y es my bueno que tomes la posta :)

También me parece bien el orden que proponés, y muy en especial
comenzar con los conceptos basicos de lvalue y rvalue.
Es que en C++11, el tema de "move" y el "&&" se apoyan en una
extensión de estos: ahora tenemos glvalue, lvalue, rvalue, xvalue y
prvalue.
Pero como diría Jack el Destripador, vayamos por partes, y sin dudas
la primera es:

> Entonces por lo que vi en los diferentes foros deberiamos empezar con esta
> simple pregunta:
> Qué es un rvalue y que es un lvalue?

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

German Garcia

unread,
Apr 12, 2012, 1:10:14 PM4/12/12
to cp...@googlegroups.com
El c++ se estará poniendo muy complicado ? O yo me estaré volviendo viejo ? :)

"ahora tenemos glvalue, lvalue, rvalue, xvalue y
prvalue." ??! Pero demonios! Yo estaba contento con apenas distinguir "más o menos" rvalue y lvalue (l factible de ir a la izquierda y r sólo a la derecha del = )


2012/4/12 Fernando Cacciola <fernando...@gmail.com>

Fernando Cacciola

unread,
Apr 12, 2012, 1:14:15 PM4/12/12
to cp...@googlegroups.com
On Thu, Apr 12, 2012 at 2:10 PM, German Garcia <ggarc...@gmail.com> wrote:
> El c++ se estará poniendo muy complicado ? O yo me estaré volviendo viejo ?
> :)
>
> "ahora tenemos glvalue, lvalue, rvalue, xvalue y
> prvalue." ??! Pero demonios! Yo estaba contento con apenas distinguir "más o
> menos" rvalue y lvalue (l factible de ir a la izquierda y r sólo a la
> derecha del = )
>

Jaja, a simple vista puede parecer complicado pero en realidad tiene
mucho sentido y justamente lo que hace es permitir que muchas otras
cosas más avanzadas se puedan expresar, entender y hasta explicar más
sencillamente. Un poco como pasa con el hecho de distinguir entre L y
R values (cuando en otros lenguajes hay solo values)

Saludos

German Garcia

unread,
Apr 12, 2012, 1:33:36 PM4/12/12
to cp...@googlegroups.com


2012/4/12 Fernando Cacciola <fernando...@gmail.com>

On Thu, Apr 12, 2012 at 2:10 PM, German Garcia <ggarc...@gmail.com> wrote:
> El c++ se estará poniendo muy complicado ? O yo me estaré volviendo viejo ?
> :)
>
> "ahora tenemos glvalue, lvalue, rvalue, xvalue y
> prvalue." ??! Pero demonios! Yo estaba contento con apenas distinguir "más o
> menos" rvalue y lvalue (l factible de ir a la izquierda y r sólo a la
> derecha del = )
>

Jaja, a simple vista puede parecer complicado pero en realidad tiene
mucho sentido y justamente lo que hace es permitir que muchas otras
cosas más avanzadas se puedan expresar, entender y hasta explicar más
sencillamente.  Un poco como pasa con el hecho de distinguir entre L y
R values (cuando en otros lenguajes hay solo values)

Saludos

:) bueno, superada la catarsis me puse a leer un poco, y aquí en SO explican un poquito:
http://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues
(en particular la 1ra respuesta sintetiza bastante)

saludos

sole

unread,
Apr 12, 2012, 3:03:22 PM4/12/12
to cp...@googlegroups.com
Bueno para mi lvalue y rvalue era algo como:
lvalue: a la izquierda del =, son cosas que tienen nombre y ocupan un lugar un tiempo (mientras dure el scope)
rvalue: a la derecha del =, son anónimos y temporales, los valores de los enums y los non-type template parameter.

De la lista de ejemplos que tire yo diria:
1. char c; //lvalue
2. char * hola = "hola"; // hola es lvalue y "hola" rvalue
3. void fun( std::string s); // s es lvalue
4. template<class T>
void fun2( T & arg);  //T es lvalue
5. const int i =1;  //i es lvalue.... o rvalue??? este me genera dudas seguro seguro que 1 es rvalue ;)
6. int j = i; // j es lvalue
7. std::string holas = "hola"; //holas es lvalue y "hola" es rvalue...

Creo que en los programas que veo y toco día a día hay muchos lvalue y pocos rvalues :D
Que les parece?
Sole



Daniel Gutson

unread,
Apr 12, 2012, 3:06:18 PM4/12/12
to cp...@googlegroups.com


2012/4/12 sole <soledad...@gmail.com>

Bueno para mi lvalue y rvalue era algo como:
lvalue: a la izquierda del =, son cosas que tienen nombre y ocupan un lugar un tiempo (mientras dure el scope)
rvalue: a la derecha del =, son anónimos y temporales,

entonces 
   x = f()
?

 
los valores de los enums y los non-type template parameter.

De la lista de ejemplos que tire yo diria:
1. char c; //lvalue

c = 1;
x = c;


pensálo más :)



--
Who’s got the sweetest disposition?
One guess, that’s who?
Who’d never, ever start an argument?
Who never shows a bit of temperament?
Who's never wrong but always right?
Who'd never dream of starting a fight?
Who get stuck with all the bad luck?

sole

unread,
Apr 12, 2012, 3:37:15 PM4/12/12
to cp...@googlegroups.com
Hola Dani,
x = f() juega algo mas, hay temporales que se crean a la hora de devolver o copiar, esos temporales son rvalue, pero x es un lvalue
por que me decis pensalo mas..
char c; no declaro aqui un lvalue?
c= 1; //1 es el rvalue
x = c; //x y c son lvalue

Nico Bertoa

unread,
Apr 12, 2012, 3:40:09 PM4/12/12
to cp...@googlegroups.com
En x = f(), f puede devolver algo por valor (rvalue) o algo por referencia (lvalue) segun entiendo
Game Development Portfolio: https://sites.google.com/site/nicolasbertoa/


Daniel Gutson

unread,
Apr 12, 2012, 3:40:37 PM4/12/12
to cp...@googlegroups.com


2012/4/12 sole <soledad...@gmail.com>

Hola Dani,
x = f() juega algo mas, hay temporales que se crean a la hora de devolver o copiar, esos temporales son rvalue, pero x es un lvalue
por que me decis pensalo mas..
char c; no declaro aqui un lvalue?
c= 1; //1 es el rvalue
x = c; //x y c son lvalue

c es un rvalue en el caso anterior.

Una variables es a la vez un lvalue y un rvalue.

Te muestro un pedazo del intérprete q hicimos en el primer proyecto de moto:

typedef XXXXXX Value;

struct RValue
{
    virtual Value getValue() = 0;
};

struct LValue
{
    virtual void setValue(Value val) = 0;
};

class AVariable : public RValue, public LValue
{ ... };

class AFunction : public RValue
{ ... };

Daniel Gutson

unread,
Apr 12, 2012, 3:43:52 PM4/12/12
to cp...@googlegroups.com
sigo un cacho más:

struct Statement
{
    virtual void execute() = 0;
};

class Assignment : public Statement
{
    LValue* const lvalue;
    RValue* const rvalue;

    virtual void execute()
    {
        lvalue->setValue( rvalue->getValue() );
    }

public:
    Assignment( LValue* l, RValue* r ) : lvalue(l), RValue(r) {}
};


entonces el parser en algún momento podía hacer...

  program.addStatement(  new Assignment( new Variable, new FunctionCall ) );

2012/4/12 Daniel Gutson <daniel...@gmail.com>

sole

unread,
Apr 12, 2012, 3:59:49 PM4/12/12
to cp...@googlegroups.com
Hola Dani,
Vos decis que c es una rvalue en el caso anterior, pero para mi es un lvalue porque puede ir del lado izquierdo del = y denota un objeto.
y por otro lado en el standard dice:
3.10 Lvalues and rvalues [basic.lval]
1 Every expression is either an lvalue or an rvalue.
O sea que la herencia multiple en tu ejemplo no tiene sentido

En
 x = f()
como dice Nico Bertoa depende del valor de retorno de f si es referencia o no
de nuevo el standard (98) dice:
The result of calling a function that does not return a reference is an rvalue.
Y yo creo que se refiere justamente a que se crea un temporal anonimo que eso es rvalue de una...

Por ùltimo les dije que tenia dudas aqui pero yo lo creia lvalue
const int j = 2;
bueno parece que es un rvalue, segun el standard,
An lvalue refers to an object or function. Some rvalue expressions—those of class or cvqualified
class type—also refer to objects.

Y tiene sentido el que sea lvalue o rvalue y no pueda ser los dos porque luego veremos como el move y rvalue ref afectan a estos tipos

Bss
Sole

Daniel Gutson

unread,
Apr 12, 2012, 4:01:32 PM4/12/12
to cp...@googlegroups.com


2012/4/12 sole <soledad...@gmail.com>
Hola Dani,

Vos decis que c es una rvalue en el caso anterior, pero para mi es un lvalue porque puede ir del lado izquierdo del = y denota un objeto.
y por otro lado en el standard dice:
3.10 Lvalues and rvalues [basic.lval]
1 Every expression is either an lvalue or an rvalue.
O sea que la herencia multiple en tu ejemplo no tiene sentido

Una variable es un rvalue o un lvalue, "dependiendo del contexto".
Cuando la variable está del lado derecho del igual, es un rvalue,
en C++, en Java, y en la China :D

Daniel Gutson

unread,
Apr 12, 2012, 4:04:43 PM4/12/12
to cp...@googlegroups.com


2012/4/12 Daniel Gutson <daniel...@gmail.com>


2012/4/12 sole <soledad...@gmail.com>
Hola Dani,

Vos decis que c es una rvalue en el caso anterior, pero para mi es un lvalue porque puede ir del lado izquierdo del = y denota un objeto.
y por otro lado en el standard dice:
3.10 Lvalues and rvalues [basic.lval]
1 Every expression is either an lvalue or an rvalue.
O sea que la herencia multiple en tu ejemplo no tiene sentido

Una variable es un rvalue o un lvalue, "dependiendo del contexto".
Cuando la variable está del lado derecho del igual, es un rvalue,
en C++, en Java, y en la China :D

Además, el concepto es "expression", a eso me refiero con el contexto.

[expr1] = [expr2]

en ese caso sí, es o uno u otro.
Un caso particular de expresión, es leer una variable; otro caso particular de expresión, es escribirla.

Fijáte la definición de expresión.

Fernando Cacciola

unread,
Apr 12, 2012, 4:12:34 PM4/12/12
to cp...@googlegroups.com
Aclaro para que oscurezca:

Son las *expresiones* las que son l o r-value.

Entonces, una variable en si misma no es una expresión, y por tanto no
es ni l ni r ni nada value. Que no es lo mismo que decir que es tnato
l como r.. no es ninguna de las dos porque no es una expresion.

Entonces, "c", no es un value de ningún tipo. Es una variable.

Para decidir que "categoría de valor" (como se le llama a esta
taxonomía) es "algo" hay que referir a la expresion donde está ese
algo.

Esto es un poco lo que quiere decir Daniel conque depede de contexto o
que una variable es tanto una cosa como la otra. En realidad eso es
algo impreciso.

Entonces, volviendo:

"c es un rvalue en el caso anterior"

Daniel no está hablando de "c la variable" sino de la expresion del
caso anterior donde aparece c

(Daniel: pero en realidad no sé a cual te referís??)

De aquí mas, para este tema, recuerden: lo que imporan son las
expresiones. Un identificador (como c) por sí solo no es una
expresion.

sole

unread,
Apr 12, 2012, 4:22:17 PM4/12/12
to cp...@googlegroups.com
Entonces entonces...
char c;  //no es una expresion y no es nada
c = 5;   //lvalue? yo veo un objeto ahi
x = f();  //lvalue (idem anterior)
const int i=5;  //rvalue aca si

pero por otro lado las expresiones son compuestas entonces, por lo que lei (que me mando a leer dani :P )
c = 5; es un assignement-expression
formado por dos expresiones y un operador =... entonces en este caso c es una expresion lvalue y 5 rvalue ?
o esto ya no tiene sentido?
Sole


Daniel Gutson

unread,
Apr 12, 2012, 4:26:35 PM4/12/12
to cp...@googlegroups.com


2012/4/12 sole <soledad...@gmail.com>

Entonces entonces...
char c;  //no es una expresion y no es nada

 
c = 5;   //lvalue? yo veo un objeto ahi

la expresión "asignar variable c" es lvalue,
la expresión "constante 5" es un rvalue
 
x = f();  //lvalue (idem anterior)

la expresión "invocar f sin parámetros" es un rvalue;
la otra es lvalue
 
const int i=5;  //rvalue aca si

pero por otro lado las expresiones son compuestas entonces, por lo que lei (que me mando a leer dani :P )
c = 5; es un assignement-expression
formado por dos expresiones y un operador =... entonces en este caso c es una expresion lvalue y 5 rvalue ?
o esto ya no tiene sentido?

Las expresiones son lvalue xor rvalue.
Una variable puede estar tanto en una expresión lvalue o en una expresión rvalue.
Una constante sólo puede aparecer en una expresión rvalue.
Es como que las expresiones son instanciaciones en el árbol semántico, de "cosas" subyacentes.

sole

unread,
Apr 12, 2012, 4:28:22 PM4/12/12
to cp...@googlegroups.com
great!
Ahora, no era en español el foro?

Es como que las expresiones son instanciaciones en el árbol semántico, de "cosas" subyacentes.

:P

Daniel Gutson

unread,
Apr 12, 2012, 4:31:45 PM4/12/12
to cp...@googlegroups.com


2012/4/12 sole <soledad...@gmail.com>

great!
Ahora, no era en español el foro?

:)
 

Es como que las expresiones son instanciaciones en el árbol semántico, de "cosas" subyacentes.

:P


una errata: cuando dije "constante 5" quise decir "literal entera 5".

Fernando Cacciola

unread,
Apr 12, 2012, 4:49:07 PM4/12/12
to cp...@googlegroups.com
On Thu, Apr 12, 2012 at 5:26 PM, Daniel Gutson <daniel...@gmail.com> wrote:
>
>
> 2012/4/12 sole <soledad...@gmail.com>
>>
>> Entonces entonces...
>> char c;  //no es una expresion y no es nada
>
> sí
>
Más precisamente:

*exáctamente en ese punto del fuente*, c es un "declarator-id" (o sea
el nombre del objeto que estamos declarando), pero en ese contexto,
'c' no está en una expresión que denote a ese objeto que está siendo
declarado.
Entonces efectivamente no es ningún tipo de value.

>>
>> c = 5;   //lvalue? yo veo un objeto ahi
>
>
> la expresión "asignar variable c" es lvalue,
> la expresión "constante 5" es un rvalue
>

Fijate que es el operador de asignación el que define la expresion, y
por eso el lvalue "en esa línea" sige sin ser 'c' (sino la expresion
de asignacion)

Lo mismo con:

char c = 1 ;

en ese punto, c es un declarator-id (aun cuando esto es no solo una
declaración sino ademas una definicion), y sigue sin ser l o r value.

para que podamos decir si c es un l o r value tenemos que ponerlo en
un contexto donde c denote al objeto al cual está refiriendo.


>>
>> x = f();  //lvalue (idem anterior)
>
>
> la expresión "invocar f sin parámetros" es un rvalue;
> la otra es lvalue
>
>>
>> const int i=5;  //rvalue aca si
>>

Ese 'i' aparece en una expresion en el contexto donde se requiere un
lvalue, es un lvalue sin importar que sea contante (non-modifiable)
O sea, puedo hacer:

&i

porque i denota un objeto, y entonces 'i' ahí es un lvalue

NO es lo mismo un rvalue que un objeto constante

Fernando Cacciola

unread,
Apr 12, 2012, 4:57:16 PM4/12/12
to cp...@googlegroups.com
>>> const int i=5;  //rvalue aca si
>>>
>
> Ese 'i' aparece en una expresion...

Quise decir:

*SI* ese 'i' aparece en una expresion...

Y eso es algo que NO pasa en el punto de definicion, porque una
definicion no es una expresion de asignacion que resulte en un lvalue

Es decir,

if ( ( c = 3 ) == 3 )

es posible porque la asignacion es una expresion, que resulta en un
lvalue cuyo valor es el del rvalue correspondiente al segundo operando
del =

Pero,

if ( ( int c = 3 ) == 3 )

no es posible justamente porque "int c = 3" no resulta en un value (de
ningun tipo). De lo contrario eso sería valido y el operator ==
tendria un valor a la izquierda para operar.

Saludos

Reply all
Reply to author
Forward
0 new messages