尝试使用初始值设定项列表将值分配到包含任何类型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) };
}
如上所示,使用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?
答案 0 :(得分:3)
initializer_list
只允许const
访问其元素,这意味着它们无法移动,必须复制。
来自N3337,§18.9.1/ 2 [support.initlist]
initializer_list<E>
类型的对象提供对const E
类型对象数组的访问。
因此foo
的作业会尝试制作unique_ptr
的副本,当然,这会失败。
foo = { std::make_unique<int>(0), std::make_unique<int>(1) };
This answer有一些解决方法,但我不认为它们在这种情况下会有用。