c++ - STL standard containers accessors
- andrew (48/48) Oct 10 2007 Hi,
- Arjan Knepper (11/60) Oct 15 2007 No but the user of the return'ed reference might modify the vector.
Hi, Sorry for not posting this in c++.stl but it does not seem to work for me. I need to implement the Iterator design pattern. I wrote a ListCollection class: template <class Item> class ListCollection : public Collection<Item> { vector<Item> m_items; public: // Collection implementation virtual void add(const Item& pItem) { m_items.push_back(pItem); } virtual void remove(const Item&) { } virtual size_t count() const { return m_items.size(); } virtual Item& get(size_t index) const { return m_items[index]; } virtual Iterator<Item>* create_iterator() { return new ListIterator<Item>(this); } }; The problem is with the const'ness of Item& get(size_t index) method. Being constant, the method will call the const version of the std::vector operator[] which returns a const reference. Hence, I receive a compilation error because it cannot convert the return value from the const to non-const. My Collection::get() method I found logic to be const but it seems it can't be due to the implementation of the std::vector::operator[]. Looking to the std::vector class: const_reference operator[](size_type _Pos) const { // subscript nonmutable sequence return (*(begin() + _Pos)); } reference operator[](size_type _Pos) { // subscript mutable sequence return (*(begin() + _Pos)); } Now, the question is why the 2nd version it's not const also ? Afterall, it doesn't modify the vector. It's exactly as the first version. I see that using the constant version of the std vector operator[] forces the return value to be const also. But, as I see in my Collection class, there are cases when you need to access the operator[] as const but without returning the const element. The const'ness of the operator[] should indicate that the operation does not modify the container not necessary that the container itself is constant. For my Collection class, I guess one way to still keep the const'ness of the get() method (and return a const Item&) is to have a set(const Item&, size_t index) method. But i don't think it's nice. My idea is that a Collection class is an encapsulation of as it's name says, a collection of items. Modifying the elements should be allowed, i guess. Maybe I am not getting it right. Please give some advices. thanks.
Oct 10 2007
andrew wrote:Hi, Sorry for not posting this in c++.stl but it does not seem to work for me. I need to implement the Iterator design pattern. I wrote a ListCollection class: template <class Item> class ListCollection : public Collection<Item> { vector<Item> m_items; public: // Collection implementation virtual void add(const Item& pItem) { m_items.push_back(pItem); } virtual void remove(const Item&) { } virtual size_t count() const { return m_items.size(); } virtual Item& get(size_t index) const { return m_items[index]; } virtual Iterator<Item>* create_iterator() { return new ListIterator<Item>(this); } }; The problem is with the const'ness of Item& get(size_t index) method. Being constant, the method will call the const version of the std::vector operator[] which returns a const reference. Hence, I receive a compilation error because it cannot convert the return value from the const to non-const. My Collection::get() method I found logic to be const but it seems it can't be due to the implementation of the std::vector::operator[]. Looking to the std::vector class: const_reference operator[](size_type _Pos) const { // subscript nonmutable sequence return (*(begin() + _Pos)); } reference operator[](size_type _Pos) { // subscript mutable sequence return (*(begin() + _Pos)); } Now, the question is why the 2nd version it's not const also ? Afterall, it doesn't modify the vector.No but the user of the return'ed reference might modify the vector. It's exactly as the first version.I see that using the constant version of the std vector operator[] forces the return value to be const also. But, as I see in my Collection class, there are cases when you need to access the operator[] as const but without returning the const element.In that particular case don't use the return by 'reference'. Since that reference has to be const as well otherwise the 'const contract' might be broken. Use return by value: virtual Item get(size_t index) const { Item result = m_items[index]; return ( result ); } HTH Arjan
Oct 15 2007