Search code examples
c++referenceconst-correctness

Return constant reference from non-const function return reference value


I have a class where getting a certain member by reference involves a logic, so I created a private getter function for it, which is working fine internally.

I would also want to provide public access to the same reference, but with a constant modifier. As the public function should not modify the state of the class, it is declared with the const keyword. However the internal logic, because it provides a reference to an internal member by design it should not be declared const.

How am I able to use the same logic for getting the reference, and provide a both const and non-const access point to it?

Is there a pattern I'm missing here?

Below I compiled a small example to demonstrate:

class my_class{
public:

  const int& get_my_field() const{
    return get_my_field_ref(); //g++: error: error - passing 'const my_class' as 'this' argument discards qualifiers [-fpermissive]
  }

private:
    int field;

    int& get_my_field_ref(){ //g++: warning: note - in call to 'int& my_class::get_my_field_ref()'
      /* ..complex logic to get reference.. */
      return field;
    }
};

Solution

  • After thinking it through, the problem lies in the design mostly.

    What the example program failed to mention was that the "complex logic" was to get an index inside an array. So with this information in mind, the logic to calculate the indices could be separated, and used in both const and non-const interfaces.

    #include <iostream>
    
    using namespace std;
    
    
    class my_class{
    public:
    
      const int& get_my_field() const{
        return field[complex_logic_to_get_reference()];
      }
    
    private:
        int field[5];
    
        int complex_logic_to_get_reference() const{
          int result_index = 0;
          /* Complex logic to get reference */
          return result_index;
        }
    
        int& get_my_field_ref(int index){
          return field[complex_logic_to_get_reference()];
        }
    };
    
    int main(int argc, char *argv[])
    {
        return 0;
    }
    

    My apologies to @j6t and @Peter for leaving this information out at the time of posting the question, the concept really just clicked now.