tags:

views:

162

answers:

4
 #include "iostream"
 #include "vector"


 class ABC {

  private:
      bool m_b;
  public:
      ABC() : m_b(false) {}

      ABC& setBool(bool b) {
          m_b = b;
          return *this;
      }

      bool getBool() const {
          return m_b;
      }
};

 void foo(const std::vector<ABC> &vec) {

      vec[0].setBool(true);
 }

 int main(int argc, char*argv[]) {

     std::vector<ABC> vecI;
     ABC i;
     vecI.push_back(i);
     foo(vecI);
 }

When I compile it I get this error: passing const ABC as this argument of ABC& ABC::setBool(bool) discards qualifiers

Any ideas why this would happen since the object itelf is not a constant.

+6  A: 

foo takes vec by reference-to-const, and you cannot change a const. So either remove the line that calls setBool, or if you really want to set the bool, change the argument type to std::vector&.

Or to be more strict about the implementation... You see, these two functions exist:

T& vector<T>::operator[](int);  
T const& vector<T>::operator[](int) const;

When you call "vec[i]" on a const object, only the second one is valid, so it gets selected. But this overload obviously returns T const&, and that's the thing you can't change.

To add some detail here, the vector has two operator[], a non-const one returning a reference and a const one returning a const reference. Because your vector is passed by const reference, the compiler picks the const operator[], so setBool is invoked on a const ABC (reference).
you were about 18.5 secs late with this comment lol -.-
did he make it purposely? now we all see you had to edit it mwahaha
Johannes Schaub - litb
+1 to unwesen. You should have made that an answer instead of a comment, it's less confusing than Iraimbilanja's answer. I'd have upmodded you. :-)
mhenry1384
A: 

foo takes a const vector &, meaning that the contents of the vector cannot be modified. This, in turn, means that you are not allowed to call a non-const member function on any of the elements of vec, and setBoo.

Dima
A: 

The object probably is const. Although the vector contains ABCs and not const ABCs, the vector itself is const, so when you call operator[] on it, the const version of the operator is used. The const version of operator[] on a vector returns a vector::const_reference. So, from what I can tell you are trying to call a non-const method on a const ABC&.

Joel
A: 

As another workaround, you could store pointers to ABC objects in the vector and it will work fine - albeit at the extra cost of managing the cleanup. In this case you are not modifying the contents of the vector since the vector is only holding pointers.

Stephen Doyle