質問: std::forward(arg);//引数が左辺値ならコピー,右辺値ならムーブになる #endif } // // メイン関数 // int main(void) { std::cout << "/////////////////////////////////////////////" << std::endl; std::cout << "左辺値代入" << std::endl; Hoge lr; func(lr); std::cout << "/////////////////////////////////////////////" << std::endl; std::cout << "右辺値代入" << std::endl; func(Hoge()); return 0; } ``` ### 問題を発生させなかった場合の実行結果 ``` ///////////////////////////////////////////// 左辺値代入 コピー ///////////////////////////////////////////// 右辺値代入 ムーブ ``` ちゃんと左辺値代入でも右辺値代入正しい挙動をしています。 ### #define PROBLEM_OCCURRED_1を有効にした場合の実行結果 ``` ///////////////////////////////////////////// 左辺値代入 ///////////////////////////////////////////// 右辺値代入 コピー ``` 左辺値代入時コピーが行われず右辺値代入時もコピーが行われてしまっている。 ### #define PROBLEM_OCCURRED_2を有効にした場合の実行結果 ``` ///////////////////////////////////////////// 左辺値代入 コピー ///////////////////////////////////////////// 右辺値代入 コピー ``` 右辺値代入時ムーブが行われずコピーがが行われてしまっている。 ### 開発環境の備考 | ツールの種類 | ツールの名前 | バージョン | | --- | --- | --- | | コンパイラ | clang++ | 6.0.0 | | OS | Linux Mint | 18.3 |
回答: クラス`Hoge`のムーブコンストラクタ定義に問題があるようです。質問文にある実装(★箇所)では、ムーブコンストラクタ内でコピー代入演算子が呼び出されます。 ``` struct Hoge{ Hoge()noexcept = default; ~Hoge() = default; Hoge& operator=(const Hoge& hoge)noexcept{std::cout << "コピー" << std::endl; return *this;} Hoge& operator=(Hoge&& hoge)noexcept{std::cout << "ムーブ" << std::endl; return *this;} Hoge(const Hoge& hoge)noexcept{*this = hoge;} Hoge(Hoge&& hoge)noexcept{*this = hoge;} // ★ }; ``` 正しくは、次のように実装すべきです。 ``` struct Hoge{ // (省略) Hoge(Hoge&& hoge)noexcept{*this = std::move(hoge);} }; ```