once_flag可以移动吗?

Could once_flag be movable?

怎么来的,标准没说once_flag的可移动性?我希望与 std::mutex 相同的论据适用。至少对于 gcc(4.8 版)来说,移动似乎被禁用了。如果某个编译器允许移动,最终可能会得到不可移植的代码。

大纲是 (§30.4 [thread.mutex])

struct once_flag {
    constexpr once_flag() noexcept;
    once_flag(const once_flag&) = delete;
    once_flag& operator=(const once_flag&) = delete;
};

由于复制构造函数和复制赋值运算符是用户声明的(并显式删除),移动构造函数和移动赋值运算符未隐式声明(§12.8 [class.copy]/p9, 20):

9 If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if

  • X does not have a user-declared copy constructor,
  • X does not have a user-declared copy assignment operator,
  • X does not have a user-declared move assignment operator, and
  • X does not have a user-declared destructor.

20 If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly declared as defaulted if and only if

  • X does not have a user-declared copy constructor,
  • X does not have a user-declared move constructor,
  • X does not have a user-declared copy assignment operator, and
  • X does not have a user-declared destructor.

因此,once_flag无法移动。