以下のようなクラスを考えます:
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_constructible
や std::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