2016-06-01 2 views
2

へのベクターの端から消去の最適化:私は常にstd::vector::resizeであることを読んでいるので、私は求めていますそれはコンパイラがこのコードを最適化することを法的および可能ですリサイズ

std::vector<T> my_vec(10); 
//some code 
my_vec.resize(5); 

:へ

std::vector<T> my_vec(10); 
//some code 
my_vec.erase(my_vec.begin()+5,my_vec.end()); 

最後からstd::vector::eraseを超えて消去するときは、しかし、私はstd::vector::eraseが読みやすくなっています。

+3

あなたはそれが望ましいと思いますが、その根拠は何ですか? – SergeyA

+0

私はそれをいくつかの答えで見ました。私は理由が何であるのか、理由が言及されているかを覚えていません。たぶん私はそれが本当に良いかどうか最初に尋ねるべきです:) –

+1

@HumamHelfawi:いいえ、どうして**あなたが「消去」が良く見えると思いますか? –

答えて

9

タイプ要件が異なります。

  • vector::resize(1-パラメータバージョン)MoveAssignableを要求しませんが、また、コンテナを成長させるために使用することができますので、DefaultInsertableMoveInsertableを必要としません。

  • vector::eraseは逆です。 MoveAssignableが必要ですが、他のものは必要ありません。中央で消去するために使用できるためです。

  • vector::pop_backは、上記のどれも必要としませんが、一度に1つの要素だけをポップするので、複数回呼び出す必要があります。

正常な実装では、パフォーマンスの違いは認識できません。

+0

とても役に立ちます。ありがとう –

+0

'std :: vector :: shrink_by'を持つ理由は、' pop_back'にマッチします。私は 'pop_back'のループが' shrink_by'より効率が悪いと思われますが、おそらくそうではないかもしれません:オブジェクトのデストラクタの1つがスローするとどうなりますか?通常のように@Yakk UB – Yakk

+0

標準ライブラリでのスローデストラクタの使用はUBです。 –

1

このような最適化を行うことは合法で可能ですか?はい。仕様書には、一方を他方に変換することは禁じられていません。したがって、vectorの最後からeraseの操作が収縮するのは、resizeの義務の観点から実装するのが合法です。

+1

Wait、 'resize'は逆の順序を指定していますか? –

+0

@ T.C .:ええ、私はそれも奇妙なことを発見しました。これは、 'pop_back'呼び出しのシーケンスで定義されています:' 'sz <= size()'ならば、 'pop_back()' 'size() - sz'回を呼び出すのと等価です*" –

+6

欠陥](http://cplusplus.github.io/LWG/lwg-defects.html#2160)。 C++ 14にのみ影響します。 –

関連する問題