删除显式默认函数声明时发出警告

Warning when an explicitly defaulted function declaration is deleted

如果我有编译器删除的显式默认函数声明,是否有诊断标志或工具可以警告我?

如果不是,那为什么呢?删除违约成员是否是一种理想的行为?什么时候出现这种情况,多久出现一次?


详情

我使用的是 clang 版本 5.0.1,但通过最近的 MSVC 或 gcc 版本发出警告也可以。

我所拥有的一个简化示例:

class NotMoveA
{
public:
  explicit NotMoveA(Foo f);
  ~NotMoveA() = default;
  NotMoveA(const NotMoveA &) = delete;
  NotMoveA(NotMoveA &&other) = default;
  NotMoveA &operator=(const NotMoveA &) = delete;
  //will B deleted w/o warning:
  NotMoveA &operator=(NotMoveA &&other) = default; 
  // ...
private:
  const std::string badDataMemberDisallowingMoveAssignment;
  // ...
}

并在 std::vector 中使用了 NotMoveA。由于 NotMoveA 不是 MoveAssignable,我遇到了一些错误,我花了很长时间才弄清楚原因。直接针对原因发出警告,即在已删除的 = default 函数处发出警告会有所帮助。

您需要做的是将默认成员的定义移出 class:

class NotMoveA
{
public:
  NotMoveA() = default;
  ~NotMoveA() = default;
  NotMoveA(const NotMoveA &) = delete;
  NotMoveA(NotMoveA &&other) = default;
  NotMoveA &operator=(const NotMoveA &) = delete;
  //will B deleted w/o warning:
  NotMoveA &operator=(NotMoveA &&other); 
  // ...
private:
  const std::string badDataMemberDisallowingMoveAssignment;
  // ...
};

NotMoveA & NotMoveA::operator=(NotMoveA &&other) = default;

一旦你使它成为一个越界定义,你将得到一个编译器错误,因为你不能通过 = default 定义成员函数,如果它被删除:

error: defaulting this move assignment operator would delete it after its first declaration NotMoveA & NotMoveA::operator=(NotMoveA &&other) = default;