std :: vector <std :: map <uint64_t,std :: unique_ptr <double =“”>&gt;&gt; VS2017中的编译错误

时间:2017-05-23 13:21:03

标签: c++ stdvector unique-ptr stdmap visual-studio-2017

我正在尝试编译代码:

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无法编译它?

2 个答案:

答案 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
};