interprocess
interprocess copied to clipboard
[regression] no viable constructor for offset_ptr with clang from 1.87.0
Example code could be found as below or on godbolt. The example compiles fine with VS/gcc + boost 1.87.0 or clang + boost 1.86.0. It fails with clang + boost 1.87.0.
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <map>
using namespace boost::interprocess;
managed_shared_memory g_segment(create_only, "shared", 65536);
template<typename T>
struct shared_allocator: allocator<T, managed_shared_memory::segment_manager>
{
using base_=allocator<T, managed_shared_memory::segment_manager>;
shared_allocator(): base_(g_segment.get_segment_manager()) {}
template<typename U>
struct rebind final {
using other = shared_allocator<U>;
};
};
std::map<int, int, std::less<int>, shared_allocator<std::pair<int const, int>>> mapnn;
It seems that the constructor was deleted in this commit.
//!Constructor from other offset_ptr. Only takes part in overload resolution 1Has a conversation.
//!if PointedType* is constructible from T2* other than via a conversion (e.g. cast to a derived class). Never throws.
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE explicit offset_ptr(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
, typename ipcdetail::enable_if_c<
!::boost::is_convertible<T2*, PointedType*>::value && ::boost::is_constructible<T2*, PointedType*>::value
>::type * = 0
#endif
) BOOST_NOEXCEPT
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
{}
Here's another case which fails with all the major compilers:
This change makes allocators using this pointer (like adaptive_pool) no longer meet the requirements of Allocator since it is no longer possible to cast std::allocator_traits<A>::void_pointer to std::allocator_traits<A>::pointer.