如何在不使我的对象可复制的情况下拥有一个 const 成员只移动对象?

How do I have a const member move-only object without making my object copyable?

#include<algorithm>
#include<vector>
#include<memory>

class Foo {
 public:
  Foo();

#if 1
  // Destructor for rule of 5.
  ~Foo(){}

  // Move constructor yes.
  Foo(Foo&&) noexcept = default;

  // Move assignment probably won't actually be created because const member variable.
  // Do I need it though? Why would vector need to move-assign?
  Foo& operator=(Foo&&) noexcept = default;

  // Copy no.
  Foo(const Foo&) = delete;
  Foo& operator=(const Foo&) = delete;
#endif

 protected:
  // It works if non-const. Broken if const.
  const std::unique_ptr<int> ptr;
};

int main()
{
  std::vector<Foo> bar;
  bar.reserve(1);
}

我收到错误(使用 GCC):

static assertion failed: result type must be constructible from value type of input range

但是为什么呢?

对我来说,默认构造函数和移动构造函数似乎都应该没问题。这是为了以防万一吗?我 const_cast 去掉 const 并擦除中间元素,vector 可能会尝试移动分配以“碎片整理”向量? (而如果它试图破坏+移动构造,那就行得通)

在上面的片段中 unique_ptr 代表我自己的只移动类型,所以这个问题不是关于指针的。

How do I have a const member move-only object without making my object copyable?

拥有一个 move-only 成员对象使您的 class 隐含地 non-copyable,因此无需特别做什么即可实现。


I get the error

But why?

因为你的class不满足MoveInsertable的要求。这是因为它不可移动构造。

To me it looks like both default and move constructor should be fine.

由于不可移动的成员,移动构造函数不正确。成员是 non-movable 因为它既是 non-copyable 又是 const.

结论:你可以有一个这样的class,但它不能与std::vector::reserve一起使用,因为它既不可复制也不可移动。