c++ - smart - Const vector de objetos no constantes
smart contracts ethereum (5)
Al definir una función en una interfaz:
virtual void ModifyPreComputedCoeffs ( std::vector < IndexCoeffPair_t > & model_ ) = 0;
queremos especificar que el modelo vectorial no debe modificarse en el sentido en el que las operaciones push_back, etc. no deben realizarse en el vector, pero los objetos IndexCoeffPair_t struct en el modelo_ pueden modificarse. ¿Cómo deberíamos especificar eso?
virtual void ModifyPreComputedCoeffs ( const std::vector < IndexCoeffPair_t > & model_ ) = 0;
No funciona, creo.
El concepto de constancia de C ++ está sobrevalorado por la OMI. Lo que acabas de descubrir es una de las grandes limitaciones que tiene: no se puede escalar por composición. Para poder crear un vector constante de objetos no constantes, necesita implementar su propio tipo de vector. Tenga en cuenta que, por ejemplo, incluso la biblioteca estándar tuvo que introducir nuevos tipos para const_iterators.
Mi sugerencia es usar la corrección de const en la que se ve obligado a hacerlo, y no en todos los lugares que pueda. En teoría, la corrección constante debería ayudar a los programadores, pero tiene un costo muy alto debido a la sintaxis y es muy primitivo (solo un bit, no se puede escalar por composición, incluso requiere duplicación de código).
También en mi experiencia, esta supuesta gran ayuda no es realmente tan grande ... la mayoría de los errores que detecta están relacionados con la propia maquinaria de corrección de errores y no con la lógica del programa.
¿Alguna vez se preguntó por qué la mayoría de los idiomas (incluidos los diseñados después de C ++) no implementaron esta idea?
En lugar de pasar el vector a la función, haga lo que hace la biblioteca estándar y pase un par de iteradores.
virtual void ModifyPreComputedCoeffs ( std::vector < IndexCoeffPair_t >::iterator & model_begin, std::vector < IndexCoeffPair_t >::iterator & model_end )
Es probable que esto esté en C ++ 14 como std::dynarray .
En realidad, si el tamaño es fijo en el momento de la compilación, puede usar std::array . Pero es probable que sea más útil para cosas como la programación incrustada, búferes, matrices, etc., ya que a menudo no conoce el tamaño deseado hasta el tiempo de ejecución o si desea que sea configurable.
Puede intentar crear const std::vector<YouType*>
. Entonces no puedes cambiar el vector, pero puedes cambiar los objetos dentro del vector. Pero sea preciso porque modificará los objetos originales, no las copias.
El uso de punteros inteligentes o punteros sin formato depende de los casos de uso tuyos: tienes un vector propietario o simplemente un vector de observadores.
Si puede modificar IndexCoeffPair_t
, puede agregar algunas funciones miembro const y usarlas para cambiar algunos de sus miembros haciendo que los miembros sean mutables usando la palabra clave mutable. Sin embargo, esto es una especie de pirateo, ya que ahora podría cambiar el contenido de cualquier const IndexCoeffPair_t
.
Ejemplo:
class IndexCoeffPair_t {
public:
void changeX(int newVal) const {
x = newVal;
}
private:
mutable int x;
};