Opened 8 years ago
Last modified 7 years ago
#11032 new Bugs
boost::offset_ptr needs explicit ctor
Reported by: | Owned by: | Ion Gaztañaga | |
---|---|---|---|
Milestone: | To Be Determined | Component: | interprocess |
Version: | Boost 1.57.0 | Severity: | Problem |
Keywords: | Cc: |
Description
Both the libc++ std library implementation and the MSVC library implementation require that their pointer types can be upcast.
The list and tree data structures have a class hierarchy of node types and often seem to pass pointers to the base types (or to offset_ptr<void>) that are then upcast to the most derived types. offset_ptr has no explicit constructor that allows upcasts, only implicit ctors for downcasts.
We have patched our version of offset_ptr with this constructor:
//!Explicit constructor from other offset_ptr. Never throws. template<class T2> explicit offset_ptr(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr , typename ipcdetail::enable_if_c< !ipcdetail::is_convertible<T2*, PointedType*>::value >::type * = 0) : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this)) {}
Change History (3)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
Yes, I want it to support downcasting. Sorry.
offset_ptr<Base> pb = ...; offset_ptr<Derived>pd(pb);
Does not have to compile because, as you say, raw pointers do not support this conversion, but
offset_ptr<Base> pb = ...; offset_ptr<Derived>pd = static_cast<offset_ptr<Derived>>(pb);
should compile and by consequence
offset_ptr<Base> pb = ...; offset_ptr<Derived>pd = (offset_ptr<Derived>)pb;
too, which just does a static_cast if I understand correctly. Both are used a lot in std::list and std::map implementations of Clang and MSVC.
comment:3 by , 7 years ago
Please see the table here: http://en.cppreference.com/w/cpp/concept/Allocator
The C++11 standard requires static_cast<A::pointer>(vptr)
to succeed.
I have also run into this problem when trying to use my own container, which uses void_pointer to store child pointers, with Boost.Interprocess.
I can't see the problem. offset_ptr has a constructor that allows conversions:
this allows upcasting (from derived to base). Did you mean that offset_ptr does not support downcasting (from base to derived)? It does that for good safety reasons as raw pointers don't allow those conversions. Do you want this to compile?
offset_ptr<Base> pb = ...; offset_ptr<Derived>pd(p);
whereas this is a compilation error
Base *pb = ... Derived *pd = pb;
?