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