2011-03-01 19 views
8

Cuando int i = 5;¿Los valores de propiedad son siempre constantes?

int j = i; 

Se RValue i en esta expresión sea una constante cuando se evalúa el resultado?

que estoy haciendo esta pregunta porque en mi constructor de copia su argumento requiere un const

+3

“Requiere un' const'”: Si se acepta una' const A & ', también puede pasar que algunos' A & ', ya que el elenco de no-const a const ocurre implícitamente. –

+0

Debe agregar el código de "su constructor de copia" y explicar lo que quiere decir con "requiere una' const' ". Esto ayudará a obtener una respuesta a su duda real, en lugar de una respuesta a una pregunta posiblemente engañosa. –

Respuesta

14

Hay un malentendido común en torno a los términos lvalue/rvalue. No se refieren a variables, sino a expresiones. Una expresión puede producir un valor l o un valor r, y puede ser const o no const.

En particular, en su código, la expresión i en el lado derecho de la definición int j = i; es una expresión lvalue, no un valor r. A los efectos de la asignación, existe una conversión de valor a validar y luego se asigna a la variable recién declarada.

La continuidad es un concepto ortogonal, en la mayoría de los casos, y se refiere a si puede o no puede mutar el objeto con el que está tratando.

int f(); 
int& g(); 
const int& h(); 
const int k(); 

int main() { 
    f();   // non-const rvalue expression 
    g();   // non-const lvalue expression 
    h();   // const lvalue expression 
    k();   // const rvalue expression 
    f() = 5;  // error, cannot assign to an rvalue 
    g() = 5;  // correct, can modify a non-const lvalue 
    h() = 5;  // error, cannot modify a constant lvalue 
} 

Otros ejemplos requieren el uso de tipos definidos por el usuario:

struct test { 
    void foo() { x = 5; } 
    void bar() const; 
    int x; 
}; 
test f(); 
const test g(); 
int main() { 
    f().foo();  // f() is a non-const rvalue, 
        // but you can call a method on the resulting object 
    g().foo();  // g() is a const rvalue, 
        // you cannot call a mutating member function 
    g().bar();  // but you can call a const member function 
} 
+0

Hola, ¿por qué no puedo compilar el primer ejemplo? Gracias. Traté de comentar las declaraciones de error, pero aún no compila. – user12321

+0

@ user12321: Probablemente pueda compilar pero no * enlace * ya que las funciones no están definidas (¿el error es algo así como * símbolo indefinido ... *?). Agregue un cuerpo de función como '{static int x = 10; devolver x; } 'a cada una de las funciones, comente las líneas que están marcadas como error y vuelva a intentarlo. (El 'static' está allí solo para asegurarse de que la variable esté viva después de regresar de las versiones que devuelven las referencias) –

3

En C++, rvalues ​​de tipo incorporado no puede ser const o no constante. Simplemente no tiene sentido. Sin embargo, puede haber valores const y no const de tipos de clases.

Un valor r es solo el VALOR (no el objeto/variable). ¿Qué entenderías con "valor no constante"?

+1

@Downvoter: Me pregunto qué fue lo que dije en mi respuesta. –

+0

@Armen: No soy @downvoter, pero ... Dijiste "En C++, los valores de tipo incorporado no pueden ser const o non-const". Un rvalue ** debe ** ser const o non-const. En el ejemplo de PO, i es el valor r y ** no const **. Si me declararon 'const int i = 5;', cuando se usa como un valor r, el valor r es ** const **. – qbert220

+2

@qbert: erroneo :) C++ Estándar 3.10.9 estados Los valores de clase pueden tener tipos calificados como cv; los valores r no pertenecientes a la clase siempre tienen tipos cv no calificados. Los valores R siempre tendrán tipos completos o el tipo vacío; Además de estos tipos, lvalues ​​también puede tener tipos incompletos. –

Cuestiones relacionadas