Opened 8 years ago
Last modified 8 years ago
#10540 new Bugs
missing std::nullptr_t support in boost/type_traits/is_pointer.hpp
Reported by: | Owned by: | Thorsten Ottosen | |
---|---|---|---|
Milestone: | To Be Determined | Component: | ptr_container |
Version: | Boost 1.56.0 | Severity: | Problem |
Keywords: | Cc: |
Description
...leads to a failures when inserting a nullptr into a boost::ptr_vector:
$ cat test.cc #include "boost/ptr_container/nullable.hpp" #include "boost/ptr_container/ptr_vector.hpp" void f(boost::ptr_vector<boost::nullable<int>> & v) { v.insert(v.begin(), nullptr); } $ g++ -std=c++11 -c test.cc In file included from .../boost_1_56_0/boost/ptr_container/nullable.hpp:21:0, from test.cc:1: .../boost_1_56_0/boost/mpl/eval_if.hpp: In instantiation of ‘struct boost::mpl::eval_if_c<true, boost::range_const_iterator<std::nullptr_t, void>, boost::range_mutable_iterator<std::nullptr_t, void> >’: .../boost_1_56_0/boost/range/iterator.hpp:69:17: required from ‘struct boost::range_iterator<std::nullptr_t, void>’ .../boost_1_56_0/boost/range/begin.hpp:106:61: required by substitution of ‘template<class T> typename boost::range_iterator<const T>::type boost::range_adl_barrier::begin(const T&) [with T = std::nullptr_t]’ .../boost_1_56_0/boost/ptr_container/ptr_sequence_adapter.hpp:421:43: required from ‘typename boost::disable_if<boost::ptr_container_detail::is_pointer_or_integral<Range> >::type boost::ptr_sequence_adapter<T, VoidPtrSeq, CloneAllocator>::insert(boost::ptr_sequence_adapter<T, VoidPtrSeq, CloneAllocator>::iterator, const Range&) [with Range = std::nullptr_t; T = boost::nullable<int>; VoidPtrSeq = std::vector<void*, std::allocator<void*> >; CloneAllocator = boost::heap_clone_allocator; typename boost::disable_if<boost::ptr_container_detail::is_pointer_or_integral<Range> >::type = void; boost::ptr_sequence_adapter<T, VoidPtrSeq, CloneAllocator>::iterator = boost::void_ptr_iterator<__gnu_cxx::__normal_iterator<void**, std::vector<void*, std::allocator<void*> > >, int>]’ test.cc:4:32: required from here .../boost_1_56_0/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<true, boost::range_const_iterator<std::nullptr_t, void>, boost::range_mutable_iterator<std::nullptr_t, void> >::f_ {aka struct boost::range_const_iterator<std::nullptr_t, void>}’ typedef typename f_::type type; ^ In file included from .../boost_1_56_0/boost/ptr_container/ptr_vector.hpp:20:0, from test.cc:2: .../boost_1_56_0/boost/ptr_container/ptr_sequence_adapter.hpp: In instantiation of ‘typename boost::disable_if<boost::ptr_container_detail::is_pointer_or_integral<Range> >::type boost::ptr_sequence_adapter<T, VoidPtrSeq, CloneAllocator>::insert(boost::ptr_sequence_adapter<T, VoidPtrSeq, CloneAllocator>::iterator, const Range&) [with Range = std::nullptr_t; T = boost::nullable<int>; VoidPtrSeq = std::vector<void*, std::allocator<void*> >; CloneAllocator = boost::heap_clone_allocator; typename boost::disable_if<boost::ptr_container_detail::is_pointer_or_integral<Range> >::type = void; boost::ptr_sequence_adapter<T, VoidPtrSeq, CloneAllocator>::iterator = boost::void_ptr_iterator<__gnu_cxx::__normal_iterator<void**, std::vector<void*, std::allocator<void*> > >, int>]’: test.cc:4:32: required from here .../boost_1_56_0/boost/ptr_container/ptr_sequence_adapter.hpp:421:43: error: no matching function for call to ‘begin(std::nullptr_t&)’ insert( before, boost::begin(r), boost::end(r) ); ^ .../boost_1_56_0/boost/ptr_container/ptr_sequence_adapter.hpp:421:43: note: candidates are: In file included from .../boost_1_56_0/boost/range/functions.hpp:18:0, from .../boost_1_56_0/boost/ptr_container/detail/reversible_ptr_container.hpp:29, from .../boost_1_56_0/boost/ptr_container/ptr_sequence_adapter.hpp:20, from .../boost_1_56_0/boost/ptr_container/ptr_vector.hpp:20, from test.cc:2: .../boost_1_56_0/boost/range/begin.hpp:97:55: note: template<class T> typename boost::range_iterator<C>::type boost::range_adl_barrier::begin(T&) inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r ) ^ .../boost_1_56_0/boost/range/begin.hpp:97:55: note: template argument deduction/substitution failed: .../boost_1_56_0/boost/range/begin.hpp:106:61: note: template<class T> typename boost::range_iterator<const T>::type boost::range_adl_barrier::begin(const T&) inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r ) ^ .../boost_1_56_0/boost/range/begin.hpp:106:61: note: substitution of deduced template arguments resulted in errors seen above In file included from .../boost_1_56_0/boost/ptr_container/ptr_vector.hpp:20:0, from test.cc:2: .../boost_1_56_0/boost/ptr_container/ptr_sequence_adapter.hpp:421:58: error: no matching function for call to ‘end(std::nullptr_t&)’ insert( before, boost::begin(r), boost::end(r) ); ^ .../boost_1_56_0/boost/ptr_container/ptr_sequence_adapter.hpp:421:58: note: candidates are: In file included from .../boost_1_56_0/boost/range/functions.hpp:19:0, from .../boost_1_56_0/boost/ptr_container/detail/reversible_ptr_container.hpp:29, from .../boost_1_56_0/boost/ptr_container/ptr_sequence_adapter.hpp:20, from .../boost_1_56_0/boost/ptr_container/ptr_vector.hpp:20, from test.cc:2: .../boost_1_56_0/boost/range/end.hpp:91:55: note: template<class T> typename boost::range_iterator<C>::type boost::range_adl_barrier::end(T&) inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r ) ^ .../boost_1_56_0/boost/range/end.hpp:91:55: note: template argument deduction/substitution failed: .../boost_1_56_0/boost/range/end.hpp:100:61: note: template<class T> typename boost::range_iterator<const T>::type boost::range_adl_barrier::end(const T&) inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type end( const T& r ) ^ .../boost_1_56_0/boost/range/end.hpp:100:61: note: template argument deduction/substitution failed:
What would fix this is:
--- boost/type_traits/is_pointer.hpp 2014-07-09 20:04:22.000000000 +0200 +++ boost/type_traits/is_pointer.hpp 2014-09-25 15:37:45.895757102 +0200 @@ -72,6 +72,10 @@ BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_pointer,T,::boost::detail::is_pointer_impl<T>::value) +#if !defined( BOOST_NO_CXX11_NULLPTR ) +BOOST_TT_AUX_BOOL_TRAIT_SPEC1(is_pointer,::std::nullptr_t,true) +#endif + #if defined(__BORLANDC__) && !defined(__COMO__) && (__BORLANDC__ < 0x600) BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_pointer,T&,false) BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_pointer,T& const,false)
Change History (2)
follow-up: 2 comment:1 by , 8 years ago
Component: | type_traits → ptr_container |
---|---|
Owner: | changed from | to
comment:2 by , 8 years ago
Replying to johnmaddock:
That's not the right fix - std::nullptr_t is not a pointer type - it's a type that's convertible to a pointer which is a whole other ball game.
Ach, right. My bad.
Note:
See TracTickets
for help on using tickets.
That's not the right fix - std::nullptr_t is not a pointer type - it's a type that's convertible to a pointer which is a whole other ball game.
I believe the correct fix is for ptr_container to provide an explicit overload for std::nullptr_t for methods like insert. Reassigning in case someone wants to apply a fix there.