Opened 5 years ago
Last modified 5 years ago
#13405 new Bugs
Tree-based containers have troubles with move-only types.
Reported by: | Owned by: | Ion Gaztañaga | |
---|---|---|---|
Milestone: | To Be Determined | Component: | container |
Version: | Boost 1.66.0 | Severity: | Problem |
Keywords: | Cc: |
Description
Specifically, move assignment doesn't work.
E.g. test.cpp:
#include <boost/container/set.hpp> #include <memory> int main() { boost::container::set<std::unique_ptr<int>> set1, set2; set2 = std::move(set1); }
Compiling with clang 5:
$ clang++-5.0 ~/tmp/test.cpp -std=c++14 -o test -stdlib=libc++ -isystem ./boost_1_66_0 In file included from /home/brd/tmp/test.cpp:1: In file included from ./boost_1_66_0/boost/container/set.hpp:28: In file included from ./boost_1_66_0/boost/container/detail/tree.hpp:25: ./boost_1_66_0/boost/container/allocator_traits.hpp:415:51: error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<int, std::__1::default_delete<int> >' { ::new((void*)p, boost_container_new_t()) T(::boost::forward<Args>(args)...); } ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./boost_1_66_0/boost/container/allocator_traits.hpp:360:28: note: in instantiation of function template specialization 'boost::container::allocator_traits<boost::container::new_allocator<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true> > >::priv_construct<std::__1::unique_ptr<int, std::__1::default_delete<int> >, const std::__1::unique_ptr<int, std::__1::default_delete<int> > &>' requested here allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...); ^ ./boost_1_66_0/boost/container/detail/node_alloc_holder.hpp:168:36: note: in instantiation of function template specialization 'boost::container::allocator_traits<boost::container::new_allocator<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true> > >::construct<std::__1::unique_ptr<int, std::__1::default_delete<int> >, const std::__1::unique_ptr<int, std::__1::default_delete<int> > &>' requested here allocator_traits<NodeAlloc>::construct ^ ./boost_1_66_0/boost/container/detail/tree.hpp:389:26: note: in instantiation of function template specialization 'boost::container::container_detail::node_alloc_holder<boost::container::new_allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::intrusive::rbtree_impl<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, void, boost::container::value_to_node_compare<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::tree_value_compare<std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::less<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::move_detail::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, true> >, unsigned long, true, void> >::create_node<const std::__1::unique_ptr<int, std::__1::default_delete<int> > &>' requested here return m_holder.create_node(other.m_data); ^ ./boost_1_66_0/boost/intrusive/detail/node_cloner_disposer.hpp:65:42: note: in instantiation of member function 'boost::container::container_detail::RecyclingCloner<boost::container::container_detail::node_alloc_holder<boost::container::new_allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::intrusive::rbtree_impl<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, void, boost::container::value_to_node_compare<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::tree_value_compare<std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::less<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::move_detail::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, true> >, unsigned long, true, void> >, true>::operator()' requested here node_ptr n = traits_->to_node_ptr(*base_t::get()(v)); ^ ./boost_1_66_0/boost/intrusive/rbtree_algorithms.hpp:59:20: note: in instantiation of member function 'boost::intrusive::detail::node_cloner<boost::container::container_detail::RecyclingCloner<boost::container::container_detail::node_alloc_holder<boost::container::new_allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::intrusive::rbtree_impl<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, void, boost::container::value_to_node_compare<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::tree_value_compare<std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::less<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::move_detail::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, true> >, unsigned long, true, void> >, true>, boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, boost::intrusive::algo_types::RbTreeAlgorithms, false>::operator()' requested here node_ptr n = base_t::get()(p); ^ ./boost_1_66_0/boost/intrusive/bstree_algorithms.hpp:1943:55: note: (skipping 3 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all) node_ptr insertion_point = target_sub_root = cloner(current); ^ ./boost_1_66_0/boost/intrusive/bstree.hpp:1040:27: note: in instantiation of function template specialization 'boost::intrusive::rbtree_algorithms<boost::intrusive::rbtree_node_traits<void *, true> >::clone<boost::intrusive::detail::node_cloner<boost::container::container_detail::RecyclingCloner<boost::container::container_detail::node_alloc_holder<boost::container::new_allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::intrusive::rbtree_impl<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, void, boost::container::value_to_node_compare<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::tree_value_compare<std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::less<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::move_detail::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, true> >, unsigned long, true, void> >, true>, boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, boost::intrusive::algo_types::RbTreeAlgorithms, false>, boost::intrusive::detail::node_disposer<boost::container::container_detail::allocator_destroyer<boost::container::new_allocator<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true> > >, boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, boost::intrusive::algo_types::RbTreeAlgorithms> >' requested here node_algorithms::clone ^ ./boost_1_66_0/boost/intrusive/rbtree.hpp:240:18: note: in instantiation of function template specialization 'boost::intrusive::bstree_impl<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, void, boost::container::value_to_node_compare<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::tree_value_compare<std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::less<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::move_detail::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, true> >, unsigned long, true, boost::intrusive::algo_types::RbTreeAlgorithms, void>::clone_from<boost::container::container_detail::RecyclingCloner<boost::container::container_detail::node_alloc_holder<boost::container::new_allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::intrusive::rbtree_impl<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, void, boost::container::value_to_node_compare<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::tree_value_compare<std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::less<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::move_detail::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, true> >, unsigned long, true, void> >, true>, boost::container::container_detail::allocator_destroyer<boost::container::new_allocator<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true> > > >' requested here { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); } ^ ./boost_1_66_0/boost/container/detail/tree.hpp:759:24: note: in instantiation of function template specialization 'boost::intrusive::rbtree_impl<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, void, boost::container::value_to_node_compare<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::tree_value_compare<std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::less<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::move_detail::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, true> >, unsigned long, true, void>::clone_from<boost::container::container_detail::RecyclingCloner<boost::container::container_detail::node_alloc_holder<boost::container::new_allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::intrusive::rbtree_impl<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::rbtree_node_traits<void *, true>, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3>, void, boost::container::value_to_node_compare<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true>, boost::intrusive::tree_value_compare<std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::less<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::move_detail::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, true> >, unsigned long, true, void> >, true>, boost::container::container_detail::allocator_destroyer<boost::container::new_allocator<boost::container::container_detail::tree_node<std::__1::unique_ptr<int, std::__1::default_delete<int> >, void *, boost::container::tree_type_enum::red_black_tree, true> > > >' requested here this->icont().clone_from ^ ./boost_1_66_0/boost/container/set.hpp:360:46: note: in instantiation of member function 'boost::container::container_detail::tree<std::__1::unique_ptr<int, std::__1::default_delete<int> >, boost::move_detail::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, std::__1::less<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::container::new_allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::container::tree_opt<boost::container::tree_type_enum::red_black_tree, true> >::operator=' requested here { return static_cast<set&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } ^ /home/brd/tmp/test.cpp:7:10: note: in instantiation of member function 'boost::container::set<std::__1::unique_ptr<int, std::__1::default_delete<int> >, std::__1::less<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::container::new_allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, boost::container::tree_opt<boost::container::tree_type_enum::red_black_tree, true> >::operator=' requested here set2 = std::move(set1); ^ /home/brd/soft/clang+llvm-5.0.0-linux-x86_64-ubuntu14.04/bin/../include/c++/v1/memory:2388:3: note: copy constructor is implicitly deleted because 'unique_ptr<int, std::__1::default_delete<int> >' has a user-declared move constructor unique_ptr(unique_ptr&& __u) noexcept ^ 1 error generated.
Attachments (1)
Note:
See TracTickets
for help on using tickets.
Suggested fix