2016-03-01 3 views
16

は、次の例を考えてみましょう:stringstreamの.str()メンバーを移動することはできますか?

#include <sstream> 
template <typename T> 
inline std::string to_string(T const & op) { 
    std::ostringstream result; 
    result << op; 
    return result.str(); 
} 

私が代わりにresult.str()の、結果を返すようにした場合は、自動的に右辺値になります。そうではない結果に含まれる文字列(私は仮定します)。私はそれがコピーされ、そのコピーが右辺値として返されることを期待しています。

だからここに私の質問は、それが法的にある:私はそれが有効な、空の文字列が残さするストリームを期待していると仮定します

return std::move(result.str()); 

。しかし、私は実際にそれを行うのに十分な確信を持っていません。

+10

returnステートメントで 'std :: move(e)'を呼び出すのは反パターンです。返された式は、とにかくrvalueとして暗黙的に扱われ、 'std :: move'を使うとコピー・エリジョンが禁止されます。 – TartanLlama

+1

@TartanLlamaあなたはあまり単純化していませんか? "std :: string std :: ostringstream :: str()&&"という関数があった場合、関数を "return std :: move(result).str();"のままにする最良の方法ではないでしょうか? – kamikaze

+0

@kamikazeええと、バウムは私があなたのリターンステートメントにある全てのパターンを 'std :: move(e)'としていると言っています。ここで 'e'はある表現です。 – TartanLlama

答えて

20

std::ostream::str実際に内部文字列のコピーを返します。したがって、動きは合法ですが、result.str()はいずれにしても右辺であり、したがってstd::moveは何も役に立ちません。何かあれば、RVOを妨げるので、やめてください。 (@TartanLlamaが正しく彼のcommentで指摘したように右辺値を返すときだけでなく、は、は一般的に成立し、「戻り値を移動しないでください」。)特に

std::moveは、内部の文字列オブジェクトには影響を与えません。ストリーム。

+0

これは恥ずかしいほど簡単でした。何らかの理由で、私はそれが参照を返すと思った。 – kamikaze

+1

@kamikaze疑問や二重チェックの際は、[documentation](http://en.cppreference.com/w/cpp/io/basic_stringstream/str) – NathanOliver

+1

@kamikazeを参照してください。[documentation] /en.cppreference.com/w/cpp/io/basic_ostringstream/str)for。 ;) –

関連する問題