c++ c++11 const-correctness

c++ - ¿Hay algún truco ninja para hacer que una variable sea constante después de su declaración?



c++11 const-correctness (7)

¿Por qué no refactorizar su código en dos funciones separadas? Uno que devuelve un a modificado y otro que funciona con este valor (sin cambiarlo nunca).

También podría envolver su objeto alrededor de un objeto de clase de soporte y trabajar con este soporte.

template <class T> struct Constify { Constify(T val) : v_( val ) {} const T& get() const { return v_; } }; void SomeFuncion() { Constify ci( Compute() ); // Compute returns `a` // process with ci }

Su ejemplo tiene una solución fácil: refactorización.

// expect a lowercase path or use a case insensitive comparator for basic_string void OpenFile(string const& path) { // I want path to be constant now ifstream ... } OpenFile( boost::to_lower(path) ); // temporaries can bind to const&

Sé que la respuesta es 99.99% no, pero pensé que valía la pena intentarlo, nunca se sabe.

void SomeFunction(int a) { // Here some processing happens on a, for example: a *= 50; a %= 10; if(example()) a = 0; // From this point on I want to make "a" const; I don''t want to allow // any code past this comment to modify it in any way. }

Puedo hacer algo similar con const int b = a; , pero en realidad no es lo mismo y crea mucha confusión. Una solución solo C ++ 0x es aceptable.

EDIT : otro ejemplo menos abstraído, el que me hizo hacer esta pregunta:

void OpenFile(string path) { boost::to_lower(path); // I want path to be constant now ifstream ... }

EDITAR : otro ejemplo concreto: Recuperar la constidad de las variables en una sección paralela .


Claro, no hay forma de hacerlo usando el mismo nombre de variable en C ++.


En realidad, no sugiero hacer esto, pero podrías usar sombras variables creativas para simular algo como lo que quieres:

void SomeFunction(int a) { // Here some processing happens on a, for example: a *= 50; a %= 10; if(example()) a = 0; { const int b = a; const int a = b; // New a, shadows the outside one. // Do whatever you want inside these nested braces, "a" is now const. } }


Puede mover el código para generar a en otra función:

int ComputeA(int a) { a *= 50; a %= 10; if (example()) a = 0; return a; } void SomeFunction(const int a_in) { const int a = ComputeA(a_in); // .... }

De lo contrario, no hay una buena manera de hacerlo en tiempo de compilación.


Un patrón que solía utilizar es "ocultar" el argumento con un _, por lo que el código se convierte

void SomeFunction(int _a) { // Here some processing happens on a, for example: _a *= 50; _a %= 10; if(example()) _a = 0; const int a = _a; // From this point on I want to make "a" const; I don''t want to allow // any code past this comment to modify it in any way. }

También puede usar solo variables const y hacer una función para calcular el nuevo valor de a, si es necesario. Tiendo más en más para no "reutilizar" variables en hacer lo más posible mis variables inmutables: si cambias el valor de algo, entonces dale un nombre nuevo.

void SomeFunction(const int _a) { const int a = preprocess(_a); .... }


Una solución sería factorizar todo el código de mutación en una expresión lambda. Haga toda la mutación en la expresión lambda y asigne el resultado a un const int en el alcance del método. Por ejemplo

void SomeFunction(const int p1) { auto calcA = [&]() { int a = p1; a *= 50; a %= 10; if(example()) a = 0; .. return a; }; const int a = calcA(); ... }


esta podría ser una forma de hacerlo, si solo está tratando de evitar otro nombre. te sugiero que lo pienses dos veces antes de usar esto.

int func () { int a; a %= 10; const int const_a = a; #define a const_a a = 10; // this will cause an error, as needed. #undef a }