1

尝试使用初始化列表将值分配给包含任何类型元素的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 一起使用的解决方法?

4

1 回答 1

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) };

这个答案有一些解决方法,但我认为它们在这种情况下不会有用。

于 2014-08-23T00:19:58.303 回答