2010-09-23 17 views
9

El ejemplo mínima del problema que estoy teniendo se reproduce a continuación:Asignación de datos de miembros en de sólo lectura estructura, clase en STL establece

#include <set> 
using namespace std; 

class foo { 
public: 
    int value, x; 
    foo(const int & in_v) { 
    value = in_v; 
    x = 0; 
    } 
    bool operator<(const foo & rhs) const { 
    return value < rhs.value; 
} 
}; 

int main() { 
    foo y(3); 
    set<foo> F; 
    F.insert(y); 

    // Now try to modify a member of the set 
    F.begin()->x=1; 
    return 0; 
} 

Con el error error: assignment of data-member ‘foo::value’ in read-only structure. Siento que me falta algo simple aquí, pero ¿por qué no puedo modificar el miembro x en mi clase?

Respuesta

16

Los objetos en un set son inmutables; Si desea modificar un objeto, es necesario:

  1. crea una copia del objeto de la set,
  2. modificar la copia,
  3. retire el objeto original de la set y
  4. insertar la copia en el set

se verá algo como esto:

std::set<int> s; 
s.insert(1); 

int x = *s.begin(); // (1) 
x+= 1;    // (2) 
s.erase(s.begin()); // (3) 
s.insert(x);  // (4) 
+0

Bueno, la parte inmutable tiene sentido ahora. ¿Es esta la forma estándar de editar un elemento en el conjunto, con las dos copias? – Hooked

+0

@Hooked: Sí; necesita hacer dos copias: una para copiar el objeto viejo fuera del conjunto y otra para copiar el nuevo objeto en el conjunto. –

2

Según la definición de operator< (es decir, considerando solo el valor return value < rhs.value e ignorando el x), me pregunto si desea un map en lugar de un set. En map, el valor secondes mutable.

8

Dado que la variable "x" no está involucrada en la comparación inferior, sería seguro en este caso hacer "x" mutable, permitiéndole modificarlo desde dentro del conjunto. Su definición de clase sería:

class foo { 
public: 
    int value; 
    mutable int x; 

    foo(const int & in_v) : value(in_v), x(0) { } 
    bool operator<(const foo & rhs) const { 
    return value < rhs.value; 
    } 
}; 

Y ahora puede usarlo en std :: set y modificar x como lo desee. En este caso, no tiene sentido mantener dos copias de la estructura de datos como lo sugirió el póster anterior.

+1

Me gusta esta respuesta MUCHO mejor. Gracias por agregarlo. – Urkle

Cuestiones relacionadas