Boost C++ Libraries: Ticket #13405: Tree-based containers have troubles with move-only types. https://svn.boost.org/trac10/ticket/13405 <p> Specifically, move assignment doesn't work. </p> <p> E.g. test.cpp: </p> <pre class="wiki">#include &lt;boost/container/set.hpp&gt; #include &lt;memory&gt; int main() { boost::container::set&lt;std::unique_ptr&lt;int&gt;&gt; set1, set2; set2 = std::move(set1); } </pre><p> Compiling with clang 5: </p> <pre class="wiki">$ 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&lt;int, std::__1::default_delete&lt;int&gt; &gt;' { ::new((void*)p, boost_container_new_t()) T(::boost::forward&lt;Args&gt;(args)...); } ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./boost_1_66_0/boost/container/allocator_traits.hpp:360:28: note: in instantiation of function template specialization 'boost::container::allocator_traits&lt;boost::container::new_allocator&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt; &gt; &gt;::priv_construct&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, const std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &amp;&gt;' requested here allocator_traits::priv_construct(flag, a, p, ::boost::forward&lt;Args&gt;(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&lt;boost::container::new_allocator&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt; &gt; &gt;::construct&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, const std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &amp;&gt;' requested here allocator_traits&lt;NodeAlloc&gt;::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&lt;boost::container::new_allocator&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::intrusive::rbtree_impl&lt;boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, void, boost::container::value_to_node_compare&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::tree_value_compare&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; *, std::__1::less&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::move_detail::identity&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, true&gt; &gt;, unsigned long, true, void&gt; &gt;::create_node&lt;const std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &amp;&gt;' 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&lt;boost::container::container_detail::node_alloc_holder&lt;boost::container::new_allocator&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::intrusive::rbtree_impl&lt;boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, void, boost::container::value_to_node_compare&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::tree_value_compare&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; *, std::__1::less&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::move_detail::identity&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, true&gt; &gt;, unsigned long, true, void&gt; &gt;, true&gt;::operator()' requested here node_ptr n = traits_-&gt;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&lt;boost::container::container_detail::RecyclingCloner&lt;boost::container::container_detail::node_alloc_holder&lt;boost::container::new_allocator&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::intrusive::rbtree_impl&lt;boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, void, boost::container::value_to_node_compare&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::tree_value_compare&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; *, std::__1::less&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::move_detail::identity&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, true&gt; &gt;, unsigned long, true, void&gt; &gt;, true&gt;, boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, boost::intrusive::algo_types::RbTreeAlgorithms, false&gt;::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&lt;boost::intrusive::rbtree_node_traits&lt;void *, true&gt; &gt;::clone&lt;boost::intrusive::detail::node_cloner&lt;boost::container::container_detail::RecyclingCloner&lt;boost::container::container_detail::node_alloc_holder&lt;boost::container::new_allocator&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::intrusive::rbtree_impl&lt;boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, void, boost::container::value_to_node_compare&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::tree_value_compare&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; *, std::__1::less&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::move_detail::identity&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, true&gt; &gt;, unsigned long, true, void&gt; &gt;, true&gt;, boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, boost::intrusive::algo_types::RbTreeAlgorithms, false&gt;, boost::intrusive::detail::node_disposer&lt;boost::container::container_detail::allocator_destroyer&lt;boost::container::new_allocator&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt; &gt; &gt;, boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, boost::intrusive::algo_types::RbTreeAlgorithms&gt; &gt;' 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&lt;boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, void, boost::container::value_to_node_compare&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::tree_value_compare&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; *, std::__1::less&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::move_detail::identity&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, true&gt; &gt;, unsigned long, true, boost::intrusive::algo_types::RbTreeAlgorithms, void&gt;::clone_from&lt;boost::container::container_detail::RecyclingCloner&lt;boost::container::container_detail::node_alloc_holder&lt;boost::container::new_allocator&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::intrusive::rbtree_impl&lt;boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, void, boost::container::value_to_node_compare&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::tree_value_compare&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; *, std::__1::less&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::move_detail::identity&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, true&gt; &gt;, unsigned long, true, void&gt; &gt;, true&gt;, boost::container::container_detail::allocator_destroyer&lt;boost::container::new_allocator&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt; &gt; &gt; &gt;' 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&lt;boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, void, boost::container::value_to_node_compare&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::tree_value_compare&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; *, std::__1::less&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::move_detail::identity&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, true&gt; &gt;, unsigned long, true, void&gt;::clone_from&lt;boost::container::container_detail::RecyclingCloner&lt;boost::container::container_detail::node_alloc_holder&lt;boost::container::new_allocator&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::intrusive::rbtree_impl&lt;boost::intrusive::bhtraits&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::rbtree_node_traits&lt;void *, true&gt;, boost::intrusive::link_mode_type::normal_link, boost::intrusive::dft_tag, 3&gt;, void, boost::container::value_to_node_compare&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt;, boost::intrusive::tree_value_compare&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; *, std::__1::less&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::move_detail::identity&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, true&gt; &gt;, unsigned long, true, void&gt; &gt;, true&gt;, boost::container::container_detail::allocator_destroyer&lt;boost::container::new_allocator&lt;boost::container::container_detail::tree_node&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, void *, boost::container::tree_type_enum::red_black_tree, true&gt; &gt; &gt; &gt;' requested here this-&gt;icont().clone_from ^ ./boost_1_66_0/boost/container/set.hpp:360:46: note: in instantiation of member function 'boost::container::container_detail::tree&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, boost::move_detail::identity&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, std::__1::less&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::container::new_allocator&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::container::tree_opt&lt;boost::container::tree_type_enum::red_black_tree, true&gt; &gt;::operator=' requested here { return static_cast&lt;set&amp;&gt;(this-&gt;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&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt;, std::__1::less&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::container::new_allocator&lt;std::__1::unique_ptr&lt;int, std::__1::default_delete&lt;int&gt; &gt; &gt;, boost::container::tree_opt&lt;boost::container::tree_type_enum::red_black_tree, true&gt; &gt;::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&lt;int, std::__1::default_delete&lt;int&gt; &gt;' has a user-declared move constructor unique_ptr(unique_ptr&amp;&amp; __u) noexcept ^ 1 error generated. </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/13405 Trac 1.4.3 Mikhail Kremniov <mkremniov@…> Wed, 17 Jan 2018 17:35:45 GMT attachment set https://svn.boost.org/trac10/ticket/13405 https://svn.boost.org/trac10/ticket/13405 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost_container_move_fix.diff</span> </li> </ul> <p> Suggested fix </p> Ticket Mikhail Kremniov <mkremniov@…> Wed, 17 Jan 2018 17:40:11 GMT <link>https://svn.boost.org/trac10/ticket/13405#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13405#comment:1</guid> <description> <p> A possible fix is attached. </p> </description> <category>Ticket</category> </item> </channel> </rss>