コピーできるけどムーブできないクラス

以下のようなクラスを考えます:

struct Hoge
{
  Hoge(){}

  Hoge( Hoge const& ) = default; // Copy は定義されている
  Hoge( Hoge && )     = delete;  // しかし, Move は明示的に delete されている

  // 代入は(とりあえず)考えないことにする
  void operator=( Hoge const& ) = delete;

};

int main()
{
  Hoge x;
  Hoge y = x;            // OK
  Hoge z = std::move(x); // NG
}


こういうクラスに対し, std::is_copy_constructiblestd::is_move_constructible
によってコピー/ムーブが出来るか否かを問い合わせると,

int main()
{
  std::cout << std::boolalpha
    << std::is_copy_constructible<Hoge>::value // true, because
    << std::endl                               // is_constructible<Hoge, Hoge const&>::value is true
    << std::is_move_constructible<Hoge>::value // false, because
    << std::endl;                              // is_constructible<Hoge, Hoge&&>::value is false
}

こんな感じで,まぁ常識的な結果が帰ってきます.


しかし,このクラスは,標準ライブラリにおける CopyConstructible の条件は満たしません.
何故ならば,あるクラスが CopyConstructible である為には,前提として
MoveConstructible である必要がある*1からです.


要するに, Hoge のようなクラスは標準ライブラリでは殆ど使えない,ということになります.


これは厄介なので,このようなクラスが定義されていた場合には,
コンパイラ側で警告を出してくれると有難いな,と,ふと思いました.
オプションは -Wimmovable-but-copyable-class とか,どうでしょうか.
余裕があったら,重複がないかチェックした上で, GCC 辺りに提案してみたいと思います.


また,標準ライブラリの std::is_copy_constructible が,
対象クラスが MoveConstructible ではない場合に微妙な感じである点も,
後で余裕があったら, Google Group 辺りで議論してみたいなぁ,とか.


どちらも,あくまで余裕があったら,ですが.

*1:Table 21 ― CopyConstructible requirements (in addition to MoveConstructible) [copyconstructible], N3337