移动构造函数的静态断言与复制构造函数不同

oLe*_*Len 11 c++ move-semantics c++11

想象一下,我有一个A移动便宜且复制费用昂贵的课程.它可能看起来像

class A {
  public: 
    [...]

  private:
    HeavyClass m;
};
Run Code Online (Sandbox Code Playgroud)

对于这个类,我想要一个静态验证,类(1)是可构造的,(2)不是简单地使用复制构造函数进行移动构造,而与是否显式声明移动构造函数无关.

这可能吗?

至于为什么我想这样做,请考虑以下示例:首先,该类自动生成移动构造函数,并根据需要运行.然后,有人更改了类并添加了析构函数,这导致不会隐式生成移动构造函数,而是使用复制构造函数.

因此,a static_assert会是理想的,但似乎这里没有is_move_constructibleis_trivially_move_constructible有帮助.

此外,我知道有可能拥有A(A&&) = default;所有这样的类,但是具有static_assert更清晰的解决方案并允许在类定义之外进行检查(在依赖于此类的其他项目中进行检查).

编辑:
我不想禁止复制构造,我只想确保移动构造函数不使用它...

Jar*_*d42 4

如果您可以更改A为间接,您可以执行以下操作:

template <bool>
struct MoveOnly {
    MoveOnly() = default;
    ~MoveOnly() = default;
    MoveOnly(const MoveOnly&) = delete;
    MoveOnly(MoveOnly&&) = default;
    MoveOnly& operator=(const MoveOnly&) = delete;
    MoveOnly& operator=(MoveOnly&&) = default;
};

template <> struct MoveOnly<false> {};

template <bool check = false>
class A_Impl : MoveOnly<check> {
public: 
    // ... as ~A_Impl() {}
    // ...
private:
    HeavyClass m;
};

using A = A_Impl<false>; // Normal case

// The check
static_assert(std::is_move_constructible<A_Impl<true>>::value, "");
Run Code Online (Sandbox Code Playgroud)

演示

  • @oLen:这就是模板的要点。动作仅用于检查,普通模式下无限制。 (2认同)
  • 可能想继承 `MoveOnly&lt;check&gt;` 而不是将其作为成员。 (2认同)