Is there some ninja trick to make a variable constant after its declaration?

后端 未结 8 1387
广开言路
广开言路 2020-12-01 09:13

I know the answer is 99.99% no, but I figured it was worth a try, you never know.

void SomeFunction(int a)
{
    // Here some processing happens on a, for ex         


        
相关标签:
8条回答
  • 2020-12-01 09:20

    this might be one way to do it, if you are just trying to avoid another name. i suggest you think twice before using this.

    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
    }
    
    0 讨论(0)
  • 2020-12-01 09:25

    A pattern I used to use is to "hide" the argument with an _, so the code becomes

    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.
    }
    

    You could also use only const variables and make a function to compute the new value of a, if necessary. I tend more en more to not "reuse" variables en make as much as possible my variables immutable : if you change the value of something , then give it a new name.

    void SomeFunction(const int _a)
    {
        const int a = preprocess(_a);
        ....
    
    }
    
    0 讨论(0)
  • 2020-12-01 09:33

    One solution would be to factor all of the mutation code into a lambda expression. Do all of the mutation in the lambda expression and assign the result out to a const int in the method scope. For example

    void SomeFunction(const int p1) { 
      auto calcA = [&]() {
        int a = p1;
        a *= 50;
        a %= 10;
        if(example())
           a = 0;
        ..
        return a;
      };
      const int a = calcA();
      ...
    }
    
    0 讨论(0)
  • 2020-12-01 09:33

    You could move the code to generate a into another function:

    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);
      // ....
    }
    

    Otherwise, there's no nice way to do this at compile time.

    0 讨论(0)
  • 2020-12-01 09:33

    Sure, there is no way to do it using the same variable name in C++.

    0 讨论(0)
  • 2020-12-01 09:35

    Why not refactor your code in to two separate functions. One that returns a modified a and another that works on this value (without ever changing it).

    You could possibly wrap your object too around a holder class object and work with this holder.

    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
    }
    

    Your example has an easy fix: Refactoring.

    // 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&
    
    0 讨论(0)
提交回复
热议问题