【问题标题】:Creating a pair from temporaries从临时对象创建一对
【发布时间】:2016-08-05 12:32:06
【问题描述】:

我尝试从临时对象中构建一对。据我了解, std::pair 提供了必要的构造函数,但我无法使其工作。这是我的最小示例:

#include <utility>

struct Test {
  Test() : a(1.0) {}

private:
  double a;
  Test(Test&&) = default;
  Test(const Test&) = delete;
  Test& operator=(Test&&) = delete;
};

int main (int argc, char** argv) {
  std::pair<Test, double> result(Test(), 0.0);
}

我尝试用clang++-3.8 --std=c++14 编译它。 Test 的复制构造函数由 pair 调用。因为它已被删除,所以我收到错误 call to deleted constructor of 'Test'。但这似乎不是编译器的问题,因为我在 gcc 中遇到了类似的错误,请参阅https://ideone.com/n5GOeR

有人可以向我解释一下为什么上面的代码无法编译吗?

【问题讨论】:

  • 既然您无法复制或移动Test,您希望std::pair 的构造函数如何做到这一点?
  • 我尝试为Test显式启用移动构造函数。
  • 将移动构造函数放入public 部分后,it works just fine

标签: c++ c++11 move


【解决方案1】:

我的 gcc (6.1.1) 给出了一个稍微不同的错误信息,这更有帮助:

t.C:8:3: note: declared private here
   Test(Test&&) = default;
   ^~~~

您的移动构造函数是私有的。显然必须是公开的。

【讨论】:

  • 奇怪的是这是(删除的)复制构造函数,重载决议不应该选择它。不知道用的是哪个版本的 GCC Ideone,但是貌似有 bug。
  • 是的,我的 gcc 提供了更好的诊断。已更新。
  • @Quentin 这很奇怪,我刚刚尝试过 gcc.godbolt.org 和从 4.4.7 开始的每个 GCC 版本(他们拥有的最古老的版本),关于移动构造函数是私有的正确错误。跨度>
  • @Quentin 但是由于某种原因,clang 尝试使用复制构造函数并抱怨它被删除。所以显然ideone使用Clang。还有一个有趣的问题:这里哪一个是正确的?
  • @IlyaPopov 绝对应该在这里选择移动构造函数:捕获右值是它的重点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-01
  • 2011-08-17
  • 2016-01-30
  • 2014-11-30
  • 1970-01-01
  • 2022-01-06
相关资源
最近更新 更多