[Boost-bugs] [Boost C++ Libraries] #11139: boost::container::vector<std::shared_ptr<const T>, std::allocator<T>>::const_iterator allows changing its dereferenced elements

Subject: [Boost-bugs] [Boost C++ Libraries] #11139: boost::container::vector<std::shared_ptr<const T>, std::allocator<T>>::const_iterator allows changing its dereferenced elements
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-03-24 15:24:53


#11139: boost::container::vector<std::shared_ptr<const T>,
std::allocator<T>>::const_iterator allows changing its dereferenced
elements
---------------------------------+------------------------
 Reporter: matteo.settenvini@… | Owner: igaztanaga
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: container
  Version: Boost 1.57.0 | Severity: Problem
 Keywords: |
---------------------------------+------------------------
 Consider the following attempt to make a `const_iterator` for a vector of
 smart pointers, be de-referentiable only to smart pointers to constant
 types:

 {{{
 #!c++
 #include <memory>

 #include <boost/container/vector.hpp>

 class C
 {
 public:
     using a_type = int;

     using shared_ptr = std::shared_ptr<a_type>;
     using shared_constptr = std::shared_ptr<const a_type>;

     // In my code, I am using a more complex allocator
     // in shared memory from boost::interprocess.
     using some_fixed_allocator = std::allocator<shared_ptr>;

     using vector = boost::container::vector<shared_ptr,
 some_fixed_allocator>;
     using cvector = boost::container::vector<shared_constptr,
 some_fixed_allocator>;

     C ()
     {
         shared_ptr p = std::make_shared<a_type> (1);
         _v.push_back (p);
     }

     cvector::const_iterator first_element () const
     {
         return _v.begin ();
     }


 private:
     vector _v;
 };


 int
 main ()
 {
     C c;

     C::cvector::const_iterator it = c.first_element ();
     **it = 2; // Expecting an error!

     // Note that we have an error using std::vector.
 }
 }}}

 This compiled cleanly with G++ 4.9 with `-std=c++11`, which really is
 hiding the problem as the const_iterator allows changing elements of a the
 `cvector` type.

 Using a std::vector at least results in the following compilation error:

 {{{
 allocator-rebind.cc: In member function
 â€˜std::vector<boost::shared_ptr<const int>, std::allocator<int>
>::const_iterator C::first_element() const’:
 allocator-rebind.cc:31:26: error: could not convert ‘((const
 C*)this)->C::_v.std::vector<_Tp, _Alloc>::begin<boost::shared_ptr<int>,
 std::allocator<int> >()’ from ‘std::vector<boost::shared_ptr<int>,
 std::allocator<int> >::const_iterator {aka
 __gnu_cxx::__normal_iterator<const boost::shared_ptr<int>*,
 std::vector<boost::shared_ptr<int>, std::allocator<int> > >}’ to
 â€˜std::vector<boost::shared_ptr<const int>, std::allocator<int>
>::const_iterator {aka __gnu_cxx::__normal_iterator<const
 boost::shared_ptr<const int>*, std::vector<boost::shared_ptr<const int>,
 std::allocator<int> > >}’
          return _v.begin ();
 }}}

 I suspect all the other containers in boost::container suffer from the
 same problem, e.g. they allow compilation of something wrong.

 Incidentally, it would be nice to have a way to rebind iterators for smart
 pointers, so that full encapsulation can be achieved also for `const`
 accessor methods.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/11139>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:18 UTC