初期化子リストを使用して、任意の型の要素をboost::multi_index::multi_index_container
含むオブジェクトに値を割り当てようとすると、コンパイル エラーが発生します。std::unique_ptr
以下に簡単な例を示します ( Wandboxにもあります)。
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <memory>
int main()
{
boost::multi_index::multi_index_container<std::unique_ptr<int>> foo;
// Works:
foo.insert(std::make_unique<int>(0));
foo.insert(std::make_unique<int>(1));
// Doesn't work:
foo = { std::make_unique<int>(0), std::make_unique<int>(1) };
}
上に示したように、各オブジェクトを一度に 1 つずつ挿入するとinsert()
機能しますが、実際にはそうする必要はありません。
Boost 1.56.0 を使用し、Visual C++ 12.0 (Visual Studio 2013 Update 3) でコンパイルしています。ただし、Clang 3.4 または GCC 4.9.0 でコンパイルすると、本質的に同じエラーが発生します。
Clang からの出力は次のとおりです (読みやすいように選択されています)。
In file included from test.cpp:1:
In file included from boost/multi_index_container.hpp:20:
boost/detail/allocator_utilities.hpp:153:11: error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<int, std::__1::default_delete<int> >'
new (p) Type(t);
^ ~
boost/multi_index/detail/index_base.hpp:105:33: note: in instantiation of function template specialization 'boost::detail::allocator::construct<std::__1::unique_ptr<int, std::__1::default_delete<int> > >' requested here
boost::detail::allocator::construct(&x->value(),v);
^
boost/multi_index/detail/index_base.hpp:144:12: note: in instantiation of member function 'boost::multi_index::detail::index_base<std::__1::unique_ptr<int, std::__1::default_delete<int> >, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > > >::insert_' requested here
return insert_(v,x,lvalue_tag());
^
boost/multi_index/ordered_index.hpp:728:33: note: in instantiation of member function 'boost::multi_index::detail::index_base<std::__1::unique_ptr<int, std::__1::default_delete<int> >, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > > >::insert_' requested here
final_node_type* res=super::insert_(v,position,x,variant);
^
boost/multi_index_container.hpp:657:27: note: in instantiation of function template specialization 'boost::multi_index::detail::ordered_index<boost::multi_index::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::multi_index::detail::nth_layer<1, std::__1::unique_ptr<int, std::__1::default_delete<int> >, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > > >, boost::mpl::vector0<mpl_::na>, boost::multi_index::detail::ordered_unique_tag>::insert_<boost::multi_index::detail::lvalue_tag>' requested here
node_type* res=super::insert_(v,position,x,variant);
^
boost/multi_index_container.hpp:669:12: note: in instantiation of function template specialization 'boost::multi_index::multi_index_container<std::__1::unique_ptr<int, std::__1::default_delete<int> >, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > > >::insert_<boost::multi_index::detail::lvalue_tag>' requested here
return insert_(v,position,detail::lvalue_tag());
^
boost/multi_index_container.hpp:339:30: note: in instantiation of member function 'boost::multi_index::multi_index_container<std::__1::unique_ptr<int, std::__1::default_delete<int> >, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > > >::insert_' requested here
hint=x.make_iterator(x.insert_(*first,hint.get_node()).first);
^
test.cpp:15:6: note: in instantiation of member function 'boost::multi_index::multi_index_container<std::__1::unique_ptr<int, std::__1::default_delete<int> >, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<std::__1::unique_ptr<int, std::__1::default_delete<int> > >, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > > >::operator=' requested here
foo = { std::make_unique<int>(0), std::make_unique<int>(1) };
^
libcxx-3.4/include/c++/v1/memory:2510:31: note: copy constructor is implicitly deleted because 'unique_ptr<int, std::__1::default_delete<int> >' has a user-declared move constructor
_LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
^
1 error generated.
ここで何が起こっているのかよくわかりません。コピー コンストラクターが呼び出されるのはなぜですか? これは単なる Boost の制限ですか? 具体的には、私のターゲット コンパイラである Visual C++ 12.0 で動作する回避策はありますか?