c++ - 可变参数构造函数优先于用户提供的 move 构造函数,默认情况下除外

标签 c++ c++11 templates variadic-templates move-semantics

考虑以下代码片段,其中我有一个只能 move 的 Wrapper 对象,该对象将参数转发给构造时的基础数据。现在,如果我在另一个仅 move 类(在本例中为 SomeObject)中使用此 Wrapper 对象,除非 SomeObject 的 move 构造函数是默认的,它无法编译。

#include <utility>

template <typename T> class Wrapper {
public:
  template <typename... Args>
  Wrapper(Args &&... args) : _data{std::forward<Args>(args)...} {}

  Wrapper(const Wrapper &) = delete;

  Wrapper(Wrapper &&other) : _data(std::move(other)) {}

  T &get() const { return _data; }

protected:
  T _data;
};

struct SomeObject {
  SomeObject(const SomeObject &) = delete;
  SomeObject(SomeObject &&other) : x(std::move(other.x)) {}
  //SomeObject(SomeObject &&other) = default; // this works!
  SomeObject(int val) : x(val) {}

  Wrapper<int> x;
};

int main() {
  SomeObject obj(10);
  return 0;
}

在 gcc 6.3 中我们得到:

test.cpp: In instantiation of ‘Wrapper<T>::Wrapper(Wrapper<T>&&) [with T = int]’: 
test.cpp:20:56:   required from here 
test.cpp:10:52: error: cannot convert ‘std::remove_reference<Wrapper<int>&>::type {aka Wrapper<int>}’ to ‘int’ in initialization
Wrapper(Wrapper &&other) : _data(std::move(other)) {}
                                                ^

我在这里遗漏了什么吗?用户在 SomeObject 中提供的 move 构造函数不是与编译器在默认情况下定义的 move 构造函数相同吗?

我能找到的唯一接近这个的是this answer但我觉得这是一个不同的情况,因为我的 SomeObject move 构造函数没有传递 const 类型。

最佳答案

这是预料之中的。查看您的代码:

Wrapper(Wrapper &&other) : _data(std::move(other)) {}
T _data;

在你的例子中,T 是整数。你想怎么初始化int来自 Wrapper<int>

关于c++ - 可变参数构造函数优先于用户提供的 move 构造函数,默认情况下除外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46613777/

相关文章:

c++ - 为什么不能推导出这个模板参数?

c++ - 在 Polycode Xcode 项目中加载框架后目录中断

c++ - 如何理解 `std::function` 的类型仅取决于其调用签名?

c++ - Linux - 从管道读取的子级接收发送到标准输出的调试消息

c++ - 我收到一条错误消息,指出只有虚拟函数可以标记为覆盖

c++ - 显式引用限定转换运算符模板的实际应用

asp.net - jQuery 模板 MIME 类型

c++ - 在定义函数时,使用decltype获取函数返回的类型

c++ - 使用 std::is_same,为什么我的函数仍然不能用于 2 种类型

c++ - VTK 7.1.1 : vtkX3DExporter exception