8

テンプレート クラス内の多くのメソッドは、オブジェクトvectorへの const 参照を取りvalue_typeます。たとえば、次のようになります。

void push_back (const value_type& val);

while値でパラメータをresize取ります:value_type

void resize (size_type n, value_type val = value_type());

専門家ではない C++ プログラマーとして、この選択の欠点しか思い浮かびません (たとえば、size_of(value_type)十分な大きさの場合、スタック オーバーフローが発生する可能性があります)。言語についてより深い洞察をお持ちの方に質問したいのは、次のとおりです。

この選択の背後にある設計上の理論的根拠は何ですか?

4

2 に答える 2

9
void resize( size_type count, T value = T() );

この関数はC++11 から削除されました。

C++11 には、次の2 つのオーバーロードがありresize()ます。

void resize( size_type count );
void resize( size_type count, const value_type& value);

これは非常に簡単に理解できます。1 つvalue_type目は、サイズ変更時にベクターを埋めるタイプのデフォルトの構築済みオブジェクトを使用し、2 つ目は、サイズ変更時にコピーを作成する値を取得します。

于 2013-05-15T16:05:36.410 に答える
6

これは設計上の欠陥のようで、現在は修正されています。

STL 欠陥 679からの引用

C++98 標準では、コンテナーの 1 つのメンバー関数だけがそのパラメーター (T) を const 参照ではなく値で渡すことを指定しています。

void resize(size_type sz, T c = T());

この事実は、C++98 が承認される前から、何年にもわたって繰り返し議論/議論されてきました。このパラメーターを値で渡す理由は次のとおりです。

そのため、自己参照ステートメントが機能することが保証されます。たとえば、次のようになります。

 v.resize(v.size() + 1, v[0]);  

ただし、push_back のシグネチャは次のとおりであるため、この理論的根拠は説得力がありません。

 void push_back(const T& x);

また、push_back には、サイズ変更 (追加) と同様のセマンティクスがあります。また、push_back は自己参照の場合でも機能する必要があります。

 v.push_back(v[0]);  // must work

T を値で渡す場合の問題は、参照渡しよりもかなりコストがかかる可能性があることです。逆も真ですが、真の場合は通常、それほど劇的ではありません (たとえば、スカラー型の場合)。

移動セマンティクスが利用可能であっても、このパラメーターを値で渡すとコストがかかる可能性があります。たとえば vector> を考えてみましょう:

std::vector<int> x(1000);
std::vector<std::vector<int>> v;
...
v.resize(v.size()+1, x);

値渡しの場合、x は一度 resize のパラメーターにコピーされます。そして、内部的には、サイズ変更によってベクトルがどれだけ大きくなったのかをコードがコンパイル時に知ることができないため、通常、x はサイズ変更のパラメータからベクトル内の適切な場所に 2 回コピーされます (移動されません)。

pass-by-const-reference を使用すると、上記の例の x を 1 回だけコピーする必要があります。この場合、 x には高価なコピー コンストラクターがあるため、保存できるコピーは大幅な節約になります。

push_back を効率的に処理できる場合は、サイズ変更も効率的に行う必要があります。参照パラメーターを使用するサイズ変更はコード化され、CodeWarrior ライブラリーに同梱されていますが、私が認識している問題の報告はありません。

決議案:

23.3.3 [deque]、p2 を変更:

class deque {
   ...
   void resize(size_type sz, const T& c);

23.3.3.3 [deque.capacity]、p3 を変更:

void resize(size_type sz, const T& c);  

変更 23.3.5 [リスト]、p2:

class list {
   ...
   void resize(size_type sz, const T& c);

23.3.5.3 [list.capacity]、p3 を変更:

 void resize(size_type sz, const T& c);

23.3.6 [ベクター]、p2 を変更:

class vector {
   ...
   void resize(size_type sz, const T& c);

23.3.6.3 [vector.capacity]、p11 を変更:

void resize(size_type sz, const T& c);
于 2013-05-15T16:12:59.190 に答える