61412


私はC++について勉強中ですが、以下のようなコードに対するメリットが発見できませんでした。

[code]

    Obj a;
    Obj&& b = std::move(a);
    
[/code]

aをrvalueとみなして、再利用しないという意味づけを行うにもかかわらず、bで参照できるようにするメリットはどこにありますか？

また、仮引数に対して用いる場合も、templateとの併用をしない場合のユースケースはありますか？  
Argument deductionを用いたtemplateと併用する場合：

[code]

    template<typename T>
    void swap(T &&a, T &&b){
        auto tmp = std::forward<T>(a);
        a = std::forward<T>(b);
        b = std::forward<T>(tmp);
    }
    
    //　単にmoveするだけなら以下でよいのではないでしょうか
    
    template<typename T>
    void swap(T &a, T &b){
        auto tmp = std::move(a);
        a = std::move(b);
        b = std::move(tmp);
    }
    
[/code]

右辺値参照を受け取る場合を明示したオーバーロードの場合では有効に使えそうです。  
以下Objの実装でのムーブコンストラクタなど：

[code]

    class Obj{
    public:
        int *data; 
        Obj(){
            Init();
        };
        ~Obj(){
            UnInit();
        }
        Obj(const Obj& other){
            Init();
            *this = other;
        };
        Obj(Obj&& other){
            Init();
            *this = std::move(other);
        };
        Obj& operator=(const Obj& other){
            std::cout << "copy" << std::endl;
            std::copy(other.data, other.data + SIZE, data);
            return *this;
        }
        Obj& operator=(Obj&& other){
            std::cout << "move" << std::endl;
            data = other.data;
            other.data = nullptr;
            return *this;
        }
        void Init(){
            data = new int(SIZE);
            std::cout << "construct" << std::endl;
        }
        void UnInit(){
            delete[] data;
            std::cout << "destruct" << std::endl;
        }
    };
    
[/code]

この他にユースケースはありますか？


CC BY-SA 4.0
2019-12-13T07:53:10.283
61405
2019-12-13T09:05:18.793
37013
question
c++ c++11
右辺値参照宣言子&&にユースケースはありますか？


>
[code]

>     Obj a;
>     Obj&& b = std::move(a);
>  
[/code]

>
> aをrvalueとみなして、再利用しないという意味づけを行うにもかかわらず、bで参照できるようにするメリットはどこにありますか？

上記コードが有用なケースは無いと思います。変数`b`は右辺値参照型`Obj&&`ではありますが、実際にムーブ操作を行うときは改めて右辺値へのキャスト`std::move(b)`が必要になります。

[code]

    Obj a;
    Obj&& b = std::move(a);
    Obj c = std::move(b);  // 変数cへムーブ
    // Obj c = b; では単にコピーが行われる
    
[/code]

* * *

> 仮引数に対して用いる場合も、templateとの併用をしない場合のユースケースはありますか？

いまひとつ質問意図を読み取れなかったのですが、C++標準ライブラリ提供の[関数テンプレート`std::swap`](https://cpprefjp.github.io/reference/utility/swap.html)では右辺値参照型`T&&`を用いません。

[code]

    template <class T>
    void swap(T& a, T& b);
    // (constexprやnoexceptは省略)
    
[/code]

* * *

> 右辺値参照を受け取る場合を明示したオーバーロードの場合では有効に使えそうです。

基本的には、まさに例示のようなクラス実装で利用されるものですね。

> この他にユースケースはありますか？

かなりのレアケースですが、[`std::ref`関数テンプレート](https://cpprefjp.github.io/reference/functional/ref.html)では「右辺値を誤って受け取らない」ように、右辺値参照型`const
T&&`が利用されています。

[code]

    // std::ref関数テンプレートのオーバーロード(一部)
    template <class T>
    reference_wrapper<T> ref(T& t);
    
    template <class T>
    void ref(const T&&) = delete;
    
[/code]


CC BY-SA 4.0
2019-12-13T09:05:18.793
61412
2019-12-13T09:05:18.793
49
61405
answer