2017-01-19 11 views
2

rvalue ref-qualifier関数からrvalue参照を返すのが本当に良いかどうかを調べています。rvalue参照修飾子はrvalue参照を返す必要がありますか?

class DataPack { 
public: 
    std::vector<int> data; 

    DataPack(std::initializer_list<int> d) : data{d} {} 

    std::vector<int>& get_data() & { 
    return data; 
    } 
    std::vector<int>&& get_data() && { 
    return std::move(data); 
    } 
    // This version fixes for-loop problem (see below) 
    //std::vector<int> get_data() && { 
    // return data; 
    //} 
}; 

その後、私は次のように使用することができ、一時的にすることなくデータを取得したい場合:

auto my_data = DataPack{1,2,3}.get_data(); 

が、私は次のコードを使用するとします。

for (auto v : DataPack{1,2,3}.get_data()) { 
    std::cout << v << ", "; 
} 

私たちは考えてみましょうこれはUBです.get_data()は、完全なステートメントの後に破棄される一時的な参照を返します。

多分、このようなループのためにこれは何とか修正できますか? RVOが期待どおりに機能することを期待して、価値あるものに戻っていくべきでしょうか?上記のように私は非常に安全でないように見えるでしょう。

+2

なぜあなたは最初に 'get_data()'を持っていますか?単に 'data'を使うだけで十分でしょう。しかし、はい、価値あるものに戻りたいと思っています。 –

+0

私はUBを見ることができません。誰がこれがUBであるのかを誰にも言えるだろうか? 'DataPack'は実際に移動されません。 –

+0

@FrançoisAndrieux: 'for'は内部的に 'auto &&'で範囲式を取り込み、' auto && __expr = DataPack {1,2,3} .get_data() 'に変わります。問題は、この式の最後に 'DataPack'が破棄されるため、' __expr'はダングリングリファレンスになります。 – ildjarn

答えて

4
std::vector<int>&& get_data() && { 
    return std::move(data); 
} 

代わりにstd::vector<int>が返されます。問題はありません。

関連する問題