【问题标题】:std::vector<std::map<uint64_t, std::unique_ptr<double>>> compilation error in VS2017VS2017 中的 std::vector<std::map<uint64_t, std::unique_ptr<double>>> 编译错误
【发布时间】:2017-05-23 13:21:03
【问题描述】:

我正在尝试编译下面的代码:

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

【问题讨论】:

  • 您不必创建empty_map_ref。只需将empty_map 直接移动到已处理的间隔中:cpp.sh/3elkk
  • 你也可以不带参数直接调用emplace_back在后面直接添加一个空地图:ideone.com/9SyNNB
  • 你试过在VS2017上编译吗?该代码适用于 GCC 和 VS2015。在 VS2017 上,我看到了同样的错误: std::vector<:map std::unique_ptr>>> processesIntervals; std::map> empty_map{}; processesIntervals.emplace_back(std::move(empty_map));
  • emplace_back 不带参数会抛出同样的编译错误

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


【解决方案1】:

这是预期的行为。它可能违反直觉,但empty_map_ref,尽管它的类型,是一个左值——所以你需要move它:

processedIntervals.emplace_back(std::move(empty_map_ref));

【讨论】:

  • @MikeSmirnov 好吧,在这种情况下,这是一个实现错误。
  • @MikeSmirnov 见this online demo。如果在 VS2017 上无法编译,则需要提交错误报告。
  • 我倾向于提交错误,因为 GCC 和 VS2015 在这段代码中运行良好。但是,我想和聪明的人一起检查一下:-)
  • @mike 我发现你的代码更有可能出错,因为你在 OP 中的例子有这样的缺陷。
【解决方案2】:

因为代码错误。正确的是

processedIntervals.emplace_back(std::move(empty_map_ref));

或直接

processedIntervals.emplace_back(std::move(empty_map));

甚至

processedIntervals.emplace_back();

由于empty_map_ref 是一个命名对象,您必须显式调用std::move 以确保右值引用。这与移动构造函数相同:

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

【讨论】:

  • 你真的在 VS2017 上编译我的代码吗? std::map>&& empty_map_ref = std::move(empty_map);处理间隔.emplace_back(empty_map_ref);与 processesIntervals.emplace_back(std::move(empty_map)); 相同您可以尝试编译您这边的代码。看起来问题不在代码中(可以通过 VS2015 编译)。
  • 不,不一样。我不在windows机器上,也没用过VS20XX编译器
猜你喜欢
  • 2014-05-12
  • 2015-10-11
  • 1970-01-01
  • 2019-11-07
  • 2018-02-02
  • 2015-01-04
  • 2022-12-07
  • 1970-01-01
  • 2020-10-09
相关资源
最近更新 更多