8

std::vectorテンプレート引数を使用してテンプレート化されたクラスがあります。引数は、デフォルトで構築可能でない可能性があります。ベクターのサイズを小さくしたい(所定のサイズにカットしたい)。明らかに

vec.resize( reduced_size );

...デフォルトのコンストラクターが必要なため、機能しません。

もちろんできます:

  1. 使用されている型の既定のコンストラクターを作成します (これは、設計上の適切な選択ではない場合に追加する必要があります)。
  2. 関数にデフォルト値を渡します(インターフェースの無用な混乱)
  3. 構築方法をテンプレートに渡します (これも役に立たない混乱)

erase質問を書いているときに、ベクターから最後まで要素を取得できることに気付きました。

vec.erase ( vec.begin() + position, vec.end() );

...しかし、これが と同じくらい効率的かどうかはわかりませんresize

デフォルトのコンストラクターなしでベクターのサイズを縮小する効率的な方法はありますか?

C++11 ソリューションは許容されます。


編集: MSVC と GCC の両方がサイズ変更の縮小を消去呼び出しとして実装しているように見えるため、パフォーマンスに関する質問に答えます。

4

3 に答える 3

2

使用するあなたのアイデアeraseは正しいルートです。混乱を減らすために、コンテナ ベースのアルゴリズムを作成します。

template<typename Container>
Container&& reduce_size( Container&& c, std::size_t amount ) {
  amount = std::min( amount, c.size() ); // paranoid!
  c.erase( end(c)-amount, end(c) );
  return std::forward<Container>(c); // I like my container-algorithms to pass through
}

これは、実装と同じくらい高速になりますerase(つまり、もう 1 つのブランチとチェック)。

使用する:

std::vector< Foo > blah;
blah.emplace_back( 7 );
reduce_size( blah, 10 );
于 2013-06-12T00:28:02.013 に答える
1

確かに -- を呼び出すときresizeに、正しい型の値を渡す 2 番目のパラメーターを指定できます。この値はresize、ベクトルのサイズを大きくするために使用する場合に (理論的には) 空のスポットを埋めるために使用されます。C++03 では、その引数のデフォルト値は ですT()。これは、デフォルトの ctor が入る場所です (C++11 では代わりにオーバーロードを使用するため、resize()問題なくサイズを縮小するために呼び出すことができます)。

独自の値を渡すことで、デフォルトの ctor が不要になります。上記のように、C++11 では、2 番目の引数を渡さなくても、デフォルトの ctor は必要ありません/使用されません。

ただし、使用する場合と比較して、これが実際の改善をもたらすとは思えませeraseん。特に、標準の仕様は次のとおりです (§23.3.6.3/9):

の場合sz <= size()、 と同等erase(begin() + sz, end());です。

そのため、この場合resize、 との間に違いがある本当の理由はないようです。erase

于 2013-06-12T00:27:01.217 に答える