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);