Prev: Using friend functions to overload operators
Next: C++ How to Program, 7/E Deitel & Deitel instructors solution manual ch 1-27 is available at affordable prices. Email at allsolutionmanuals11[at]gmail.com if you need to buy this. All emails will be answered ASAP.
From: Jonathan Campbell on 9 Dec 2009 11:37 For teaching purposes, I have a std::vector like class: template <class T> class Array{ public: ... T& operator[](unsigned int i) const; ... private: unsigned int sz_, cap_; T* dat_; }; In the middle of a (teaching) class I began to wonder, aloud :(, why Array<int> a(10); a[5] = 33; did not generate a compiler error; according to a small 'test' program it does not. Would it have to be: const T& operator[](unsigned int i) const; to generate the expected compiler error? Scratching my head further, I suppose I should have const T& operator[](unsigned int i) const; and T& operator[](unsigned int i); as std::vector has, but I'm wondering how the compiler decides which to call in for eaxample int x = a[5]; a[5] = 33; TIA, Jon C. -- Jonathan Campbell www.jgcampbell.com BT48, UK.
From: Alf P. Steinbach on 9 Dec 2009 11:47 * Jonathan Campbell: > For teaching purposes, I have a std::vector like class: > > template <class T> class Array{ > public: > ... > T& operator[](unsigned int i) const; > > ... > private: > unsigned int sz_, cap_; > T* dat_; > }; > > In the middle of a (teaching) class I began to wonder, aloud :(, why > > Array<int> a(10); > > a[5] = 33; > > did not generate a compiler error; according to a small 'test' program > it does not. > > Would it have to be: > > const T& operator[](unsigned int i) const; > > to generate the expected compiler error? Yes. What matters is the constness of the object that you assign to. Constness of things used in the expression to produce a reference to that object, doesn't matter. > Scratching my head further, I suppose I should have > > const T& operator[](unsigned int i) const; > > and > > T& operator[](unsigned int i); > > as std::vector has, but I'm wondering how the compiler decides which to > call in for eaxample > > int x = a[5]; If 'a' is const then it uses the const version, if not, not. > a[5] = 33; This is the same, depends only on constness of 'a'. Cheers & hth., - Alf
From: Jonathan Campbell on 9 Dec 2009 12:08 Alf P. Steinbach wrote: > * Jonathan Campbell: >> For teaching purposes, I have a std::vector like class: >> >> template <class T> class Array{ >> public: >> ... >> T& operator[](unsigned int i) const; >> >> ... >> private: >> unsigned int sz_, cap_; >> T* dat_; >> }; >> [...] >> const T& operator[](unsigned int i) const; >> >> and >> >> T& operator[](unsigned int i); >> >> as std::vector has, but I'm wondering how the compiler decides which >> to call in for eaxample >> >> int x = a[5]; > > If 'a' is const then it uses the const version, if not, not. > > >> a[5] = 33; > > This is the same, depends only on constness of 'a'. > > Thanks, that answers my question and another generated by my running some tests with print statements in the two versions of operator[]. I was starting to wonder why Array <int> a(10); int x = a[5]; called the non-const one. Best regards, Jon C. -- Jonathan Campbell www.jgcampbell.com BT48, UK.
From: Stuart Golodetz on 9 Dec 2009 12:54 Jonathan Campbell wrote: > Alf P. Steinbach wrote: >> * Jonathan Campbell: >>> For teaching purposes, I have a std::vector like class: >>> >>> template <class T> class Array{ >>> public: >>> ... >>> T& operator[](unsigned int i) const; >>> >>> ... >>> private: >>> unsigned int sz_, cap_; >>> T* dat_; >>> }; >>> > [...] >>> const T& operator[](unsigned int i) const; >>> >>> and >>> >>> T& operator[](unsigned int i); >>> >>> as std::vector has, but I'm wondering how the compiler decides which >>> to call in for eaxample >>> >>> int x = a[5]; >> >> If 'a' is const then it uses the const version, if not, not. >> >> >>> a[5] = 33; >> >> This is the same, depends only on constness of 'a'. >> >> > > Thanks, that answers my question and another generated by my running > some tests with print statements in the two versions of operator[]. > > I was starting to wonder why > > Array <int> a(10); > > int x = a[5]; > > called the non-const one. > > Best regards, > > Jon C. A further point worth observing (if you haven't already) is that the reason you can write T& operator[](unsigned int i) const { return dat_[i]; } without any problem is that the constness of *this here only affects dat_, not what it points to. In other words, within the above operator[], dat_ gets treated as if it were of type T *const, not const T * (so you can still get a non-const reference to the element). Moral of the story being that it's an easy one to mess up on. Cheers, Stu
From: Jonathan Campbell on 9 Dec 2009 13:08
Stuart Golodetz wrote: > Jonathan Campbell wrote: >> Alf P. Steinbach wrote: [...] > > A further point worth observing (if you haven't already) is that the > reason you can write > > T& operator[](unsigned int i) const > { > return dat_[i]; > } > > without any problem is that the constness of *this here only affects > dat_, not what it points to. In other words, within the above > operator[], dat_ gets treated as if it were of type T *const, not const > T * (so you can still get a non-const reference to the element). Moral > of the story being that it's an easy one to mess up on. > Very easy :( Thanks. If I had been called upon to explain the nature of the version above, the explanation would have been much less to the point than what you have given. Jon C. -- Jonathan Campbell www.jgcampbell.com BT48, UK. |