Mirando a las otras preguntas con respecto a error C2106, todavía estoy perdido en cuanto a cuál es el problema con mi código. Al compilar me sale el siguiente error:

c:\driver.cpp(99): error C2106: ‘=’ : a la izquierda el operando debe ser l-valor

c:\driver.cpp(169): error C2106: ‘=’ : a la izquierda el operando debe ser l-valor

La línea de código es como sigue:

payroll.at(i) = NULL; //Line 99
payroll.at(count++) = ePtr; //Line 169

Estoy fallando a entender por qué este error se produce. En este proyecto he cambiado mi driver.cpp a partir de una matriz de empleado punteros de objeto personalizado para un Vector de plantilla que he hecho. Declaro el Vector de la siguiente manera…

//Declare an Vector to hold employee object pointers
MyVector <employee*> payroll;

Cualquier ayuda es muy apreciada…

  • ¿Qué MyVector::el retorno?
  • MyGuess : YourVector::at() debe ser devuelta por el valor que es el problema.
  • esto es lo que devuelve… ‘volver myArray[n];» a menos que la referencia es mayor que el tamaño del vector, a continuación, devuelve el valor que se pasa a la función.
  • ¿Cuál es el tipo de retorno (que determina la forma de devolver lo que usted retorno)?
InformationsquelleAutor KQball | 2013-07-29

4 Comentarios

  1. 12

    Este error está siendo arrojado por la misma razón que usted no puede hacer algo como esto:

    36 = 3;

    Su versión de Vector::at debe devolver una referencia en lugar de un valor.

    Lvalues se llaman Lvalues puesto que pueden aparecer en la parte izquierda de una asignación. Rvalues no aparecen en el lado izquierdo, que es por eso que los llamamos rvalues. Usted no puede asignar 3 a 36 porque 36 no es un lvalue, es un r-value, en un temporal. No tiene una dirección de memoria. Por la misma razón, no se puede asignar NULL a payroll.at(i).


    Su definición:

    template <class V> V MyVector<V>::at(int n)

    Lo que debe ser:

    template<typename V> V& MyVector::at(std::size_t n)
    template<typename V> const V& MyVector::at(std::size_t n) const
    • Bueno, estoy buscando en el google docs y dice que devuelve una referencia.. seguro?
    • Estás en lo correcto, pero esta es una implementación personalizada de un vector
    • MyVector lol.. lo siento, hombre.
    • En el supuesto de un avance dirigido diseño de memoria, la paramater de at debe ser unsigned.
    • El parámetro de at probablemente debería ser size_t, pero eso no es realmente el problema más grande aquí.
    • Lo que está mal con la respuesta, aparte de que?
    • No me refiero a que hay un problema con la respuesta, quiero decir que fue además el punto de la pregunta original. Lo siento por la confusión.
    • Sí, pero se dice que «Lo que debe ser:» pero es likeley no es el caso, ya que debe estar sin firmar para lo at de un vector hace normalmente.
    • Dos son correctas. He utilizado std::size_t por lo que es idéntica a la definición de std::vector::at ~

  2. 5

    Que dice el mensaje que intenta asignar a una expresión que no es un lvalue. Para los tipos integrados, sólo se pueden asignar a lvalues (que es de donde viene el nombre: lvalue = valor que puede estar en el izquierda lado del operador de asignación, mientras que r-value = valor que debe estar en el derecho lado del operador de asignación).

    Entonces, ¿qué es un lvalue o un r-value? Considere el siguiente código:

    int a;
    a = 3;

    En esta asignación a es un lvalue (si no fuera, el compilador se queja). Es decir, la expresión a se refiere a un objeto que puede ser modificado. Por otro lado, 3 es un r-value, que es, básicamente, un valor. Por supuesto no se puede asignar a 3; el compilador se queja acerca de la declaración 3=a; con exactamente el mismo mensaje que puse en el código.

    Así como un primera aproximación, un lvalue designa un objeto, mientras que un r-value designa un valor. Tenga en cuenta que esto también es cierto para la asignación de la forma

    a = b;

    donde b también es una variable. Lo que sucede aquí es el llamado lvalue a r-value de conversión: ¿Qué es asignado no es el objeto b, pero su valor actual.

    Ahora considere el siguiente caso:

    int f();
    f() = 3;

    Aquí, se podría argumentar que la función f devolver un objeto (si se usa algún tipo definido por el usuario, usted puede incluso ver su construcción/destrucción). Pero el compilador todavía se queja con el mensaje que recibió. Por qué?

    Bien, incluso si se considera f para devolver un objeto, es un temporal de objetos que desaparecen de inmediato. Así que no tiene mucho sentido para asignar un valor porque no se puede hacer nada con ella de todos modos después.

    Por lo tanto, esta es la segunda regla:

    Cada vez que hay una expresión que produce un objeto temporal, C++ define esa expresión como r-value.

    Y ahora llegamos a la definición de MyVector::at() el que no se muestran, pero que, de acuerdo con el mensaje de error, probablemente similar a esto:

    template<typename T>
     T MyVector<T>::at(int i)
    {
      return data[i];
    }

    Esto tiene esencialmente la misma forma como f anteriormente, como también devuelve un T (un employee* en su caso). Esta es la razón por la que el compilador se queja.

    Y que la queja es útil: Incluso si el compilador no se quejan, el código no dio lo que casi sin duda. El return instrucción devuelve un copia del objeto data[i]. Por tanto, si la declaración de payment.at(i)=NULL; había compilado, lo que en realidad iba a suceder, sería la siguiente:

    1. El objeto interno data[i] (o sin embargo usted los llamó en su código) es copiado y la copia temporal devuelto.
    2. La declaración asignado que copia temporal, pero deja el objeto original en MyVector sin cambios.
    3. La copia temporal obtiene destruye, sin dejar rastro de su asignación.

    Esto es casi seguro que no lo quería. Quería cambiar el objeto interno. Para ello, usted tiene que devolver un referencia a ese objeto. Una referencia se refiere a que el objeto se inicializa con lugar de hacer una copia. En consecuencia, una referencia, incluso cuando se devuelve, es un lvalue (ya que C++11 hay un segundo tipo de referencia que se comporta de forma diferente, pero no necesitamos preocuparnos de que aquí). Su función corregida, a continuación, lee

    template<typename T>
     T& MyVector<T>::at(int i)
    {
      return data[i];
    }

    y con esa definición, payment.at(i)=NULL; no sólo compila, pero en realidad hace lo que quiere: Cambiar el almacenado internamente i-th puntero en payment a NULL.

  3. 3

    Su función MyVector::at(unsigned) probablemente no correctamente declarados, y se parece a esto:

    T MyVector::at(unsigned i) { /* implementation detail */ }

    Lo que quiero es que se vea de esta manera:

    T& MyVector::at(unsigned i) { /* implementation detail */ }

    Observe el parámetro de referencia (&), que devolverá cualquier elemento de referencia y permiten la expresión para ser utilizado como un l-valor.

    La verdadera pregunta es, ¿por qué no utilizar std::vector lugar?

    • También, probablemente, una const sobrecarga
    • Sí, se necesitaría una constante sobrecarga. Lo mantuve simple para mayor claridad.
    • Es por eso que usted no código en C 😀
  4. 0

    el término l-valor en c++ significa que la «izquierda» el valor es del tipo incorrecto. Puesto que usted está utilizando el operador de asignación, para ser del tipo correcto debe ser un valor que se puede asignar un nuevo valor, lo que significa que no puede ser una constante. Lo más probable, su llamada a payroll.at() es devolver un valor constante en lugar de una referencia al valor real. Tratando de asignar un nuevo valor a la misma, a continuación, hará un l-valor error.

Dejar respuesta

Please enter your comment!
Please enter your name here