Return reference to a vector member variable

C++VectorReferenceConstants

C++ Problem Overview


I have a vector as member in a class and I want to return a reference to it through a getVector() function, so as to be able to modify it later. Isn’t it better practice the function getVector() to be const? However I got an error “qualifiers dropped in binding reference of type…” in the following code. What should be modified?

class VectorHolder
{
public:
VectorHolder(const std::vector<int>&);
std::vector<int>& getVector() const;

private:
std::vector<int> myVector;

};

std::vector<int> &VectorHolder::getVector() const
{
return myVector;
}

C++ Solutions


Solution 1 - C++

Since it is a const member function, the return type cannot be non-const reference. Make it const:

const std::vector<int> &VectorHolder::getVector() const
{
   return myVector;
}

Now it is okay.

Why is it fine? Because in a const member function, the every member becomes const in such a way that it cannot be modified, which means myVector is a const vector in the function, that is why you have to make the return type const as well, if it returns the reference.

Now you cannot modify the same object. See what you can do and what cannot:

 std::vector<int> & a = x.getVector();       //error - at compile time!

 const std::vector<int> & a = x.getVector(); //ok
 a.push_back(10);                            //error - at compile time!

 std::vector<int>  a = x.getVector();        //ok
 a.push_back(10);                            //ok

By the way, I'm wondering why you need such VectorHolder in the first place.

Solution 2 - C++

it's not unusual to declare both const and mutable variants, like so:

std::vector<int>& VectorHolder::getVector() {
  return myVector;
}
const std::vector<int>& VectorHolder::getVector() const {
  return myVector;
}

the underlying problem with your program is that you return a non-const reference from a const method.

std::vector<int>& VectorHolder::getVector() const {
  return myVector; // << error: return mutable reference from const method
}

so you make it const using this form:

const std::vector<int>& VectorHolder::getVector() const {
  return myVector; // << ok
}

and when this is in a non const method or the client holds a non-const reference, then you can legally use a non-const method:

std::vector<int>& VectorHolder::getVector() {
  return myVector; // << ok
}

finally, you could return a value (in some cases):

std::vector<int> VectorHolder::getVector() const {
  return myVector; // << ok
}

because the copy requires no mutation and provides no exposure to the internal data.

so you will end up declaring both variants quite often.

the results of declaring both are:

VectorHolder m;
const VectorHolder c;

m.getVector().size(); // << ok
c.getVector().size(); // << ok - no mutation

m.getVector().push_back(a); // << ok
c.getVector().push_back(a); // << error: attempt to mutate const reference because the const vector is returned

so it all works out nicely (apart from the redundancy of the methods).

Solution 3 - C++

The function getVector can be declared as const. It returns a reference that can be modified, so while the actual function doesn't modify anything in the class, the caller will be able to modify internal data.

Declare it as:

std::vector<int>& getVector();

If you want a function to return a vector that can't be modified, the use the const modifier on both the vector and the function:

const std::vector<int>& getVector() const;

Solution 4 - C++

The reason is that a const member function should only return const references. This is because in a const function, every data member becomes constant.

Therefore you have to declare the getVector() this way:

std::vector<int> &VectorHolder::getVector() const;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionarjacsohView Question on Stackoverflow
Solution 1 - C++NawazView Answer on Stackoverflow
Solution 2 - C++justinView Answer on Stackoverflow
Solution 3 - C++Some programmer dudeView Answer on Stackoverflow
Solution 4 - C++LevView Answer on Stackoverflow