我正在尝试编译代码:
std::vector<std::map<uint64_t, std::unique_ptr<double>>> processedIntervals;
std::map<uint64_t, std::unique_ptr<double>> empty_map{};
std::map<uint64_t, std::unique_ptr<double>>&& empty_map_ref = std::move(empty_map);
processedIntervals.emplace_back(empty_map_ref);
错误是:
Error C2280 'std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)':
attempting to reference a deleted function TTTT C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.10.25017\include\xmemory0 840
代码可以在VS2015中编译而不会出错。 std::pair
(而非std::map
)的相同代码效果很好。
为什么VS2017无法编译它?
答案 0 :(得分:2)
这是预期的行为。这可能是违反直觉的,但empty_map_ref
,尽管它的类型,是左值 - 所以你需要move
它:
processedIntervals.emplace_back(std::move(empty_map_ref));
答案 1 :(得分:0)
因为代码错了。正确是
processedIntervals.emplace_back(std::move(empty_map_ref));
或直接
processedIntervals.emplace_back(std::move(empty_map));
甚至
processedIntervals.emplace_back();
由于empty_map_ref
是命名对象,因此必须显式调用std::move
以确保rvalue引用。这与移动构造函数相同:
struct foo
{
std::unique_ptr<something> ptr;
foo(std::unique_ptr<something>&&p) // constructor from rvalue ref
: ptr(std::move(p)) // ptr(p) would fail exactly as in your code
};