2016-04-19 8 views
1

とペアを構築:この中で右辺値

vector<pair<string,int>> vp; 
    string s; 
    int i; 
    while(cin>>s>>i) vp.push_back({s,i}); 

は私が最後の行について興味があります。ペアはpush_backの呼び出しで作成されるため、コピーされずに移動されます。

ではなく、このように書かれていなかった場合は、次の組の構成は同じリソースを必要とする一方で、

vector<pair<string,int>> vp; 
    string s= ...; 
    int i= ...; 
    pair<string,int> p{s,i}; 
    vp.push_back(p); 

今ペアが命名され、p、したがって、それはもはや右辺値であるため、セマンティクスを動かしますもはや使用されていないので、これは値渡しとなり、コピーが作成されます。

これは、可能であれば、argリストの中にオブジェクトを構築することがパフォーマンスの向上であることを意味します。誰でも確認できますか?

+0

コンパイラの最適化によって異なります。 –

+0

2番目の例では、同じstd :: pairをpushしますが、空のstd :: stringとunknown/random int - correct? – Nick

+0

@Nick真の場合、この場合は空です(このコードはC++のfaqからです)。しかし、私はpush_backセマンティクスについてもっと心配しています – johnbakers

答えて

6

このペアはpush_backへの呼び出しで作成されるため、コピーされずに移動されますが、正しいですか?

一時的なペアが構築され、rvalue参照引数push_backにバインドされます。その後、その引数からvectorに移動されます。

vp.push_back({s,i}); 

は同等です:

vp.push_back(std::pair<std::string, int>{s, i}); 

とほぼ同等である:

std::pair<std::string, int> p{s, i}; 
vp.push_back(std::move(p)); 

あなたはは右辺値参照のオーバーロードを使用して、一時的なを必要としません。

あなたの2番目のコード例は:

pair<string,int> p{s,i}; 
vp.push_back(p); 

はい、ではなく動くのコピーを行います。いずれにしても、まだsをペアにコピーしています(一時的またはp)。だから、より良いアプローチは、同様に一時的にsを移動するには、次のようになります。

vp.push_back({std::move(s), i}); 

あるいはそもそも中間ペアを持っていないために:

vp.emplace_back(std::move(s), i); 

ところということ。これは、私には意味します可能な限り、argリストの中にオブジェクトを構築することはパフォーマンスの向上です。誰でも確認できますか?を移動

は、パフォーマンスの向上ですが、あなたは常にstd::move()関数に引数ができます - それは一時的である必要はありません。 argリスト内での構築は、移動元オブジェクトのデストラクタが呼び出されたときに影響します。

+0

'std :: move(p)'の後に 'p'がどうなるでしょうか? – johnbakers

+1

@johnbakers次にpは有効であるが未定義の状態になる – TemplateRex

1

あなたは正しいですか?

argリスト内のオブジェクトを作成することが改善されています。

ただし、しばらくお待ちください。 intは移動できません。それはコピーです。一般的にはstd::stringが移動され、これが安全なものになりますmalloc/newコール。

このすべてが可読性に影響しない場合は、それを行ってください。そうでなければ、ほとんどの場合、それは私が信じるような大きな改善ではありません。私は一つでも多くの「道」

vp.emplace_back(std::move(s), i); 

更新を示唆している

std::pair<std::string,int> p{s,i}; 
vp.push_back(std::move(p)); 

もう一つの「道」を示唆している

- それは問題で削除されたように私はcin一部を削除しました。

+0

なぜ-1? 'malloc()'のために? – Nick

+0

もちろんmallocではありません。そして、何かを必要なだけ保存する必要はありません。 – SergeyA

+0

ライブラリーに応じて、新しいものはフードの下のmallocです。 stringが空またはssoの場合、節約はまったくありません。文字列が巨大なら、新しい/ mallocとmemcpy/memmoveは避けてください。 – Nick

関連する問題