Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-const calling const member function fails with read-only location C++

Tags:

c++

constants

Following this post I implemented an accessor like

template<class T> class qv {
  virtual const T& operator[](int i) const = 0;
  T& operator[](int i) { return const_cast<T&>(static_cast<const qv*>(this)->operator[](i)); }
};
template<class T> class qq : public qv<T> {
 public:
  const T& operator[](int i) const override { return this->data[i]; }
 protected:
  T data[5];
};

but get an assignment of read-only location when trying to do something like:

int main(int argc, char** argv) {
  qq<int> q;
  q[3] = 2; // read-only location compile error, g++ 6.3
}

It's something with the inheritance that's causing issues but I don't know what or why. As an aside does it matter if I use a static or const_cast for the inner cast above?

like image 589
user2183336 Avatar asked Mar 07 '23 06:03

user2183336


1 Answers

The operator[] declared in derived class hides the one in the base class. So qv<T>::operator[] can't be found in name lookup.

(emphasis mine)

name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.

You could add using qv<T>::operator[]; to introduce the name operator[] into the derived class. e.g.

template<class T> class qq : public qv<T> {
 public:
  using qv<T>::operator[];
  const T& operator[](int i) const override { return this->data[i]; }
 protected:
  T data[5];
};

BTW: I suppose that it's a typo to declare qv<T>::operator[] as private.

like image 151
songyuanyao Avatar answered Mar 22 '23 22:03

songyuanyao