以下代码无法在gcc 5.3上编译,并出现编译器错误,原因是抱怨以某种方式调用了unique_ptr的副本构造函数。有人可以解释为什么会这样吗?
#include <iostream>
#include <memory>
#include <deque>
using Foo = std::deque<std::unique_ptr<int>>;
void foo() {
std::vector<Foo> a;
a.emplace_back(); // this fails to compile
}
Run Code Online (Sandbox Code Playgroud)
编译器错误的关键所在是:
gcc-4.9.2/include/c++/4.9.2/bits/stl_construct.h:75:7: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’ { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
vector::emplace_back 需要处理重新分配。在vector重新分配时,如果存在以下任一情况,则移动现有元素
std::is_copy_constructible);或者noexcept.否则它们将被复制。这是为了保持强大的异常安全保证。
std::deque<std::unique_ptr<int>>的移动构造函数不是noexcept(取决于实现,它可能需要分配内存)。std::deque<std::unique_ptr<int>>可以根据 进行复制std::is_copy_constructible,因为这仅检查是否存在具有正确签名的构造函数,而不检查所述构造函数的主体是否会实际编译。vector::emplace_back 因此试图复制它。