Title
resize parameter by value
Status
cd1
Section
[sequences]
Submitter
Howard Hinnant

Created on 2007-06-11.00:00:00 last changed 171 months ago

Messages

Date: 2010-10-21.18:28:33

Proposed resolution:

Change [deque], p2:

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

Change [deque.capacity], p3:

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

Change [list], p2:

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

Change [list.capacity], p3:

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

Change [vector], p2:

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

Change [vector.capacity], p11:

void resize(size_type sz, const T& c);
Date: 2007-06-11.00:00:00

The C++98 standard specifies that one member function alone of the containers passes its parameter (T) by value instead of by const reference:

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

This fact has been discussed / debated repeatedly over the years, the first time being even before C++98 was ratified. The rationale for passing this parameter by value has been:

So that self referencing statements are guaranteed to work, for example:

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

However this rationale is not convincing as the signature for push_back is:

void push_back(const T& x);

And push_back has similar semantics to resize (append). And push_back must also work in the self referencing case:

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

The problem with passing T by value is that it can be significantly more expensive than passing by reference. The converse is also true, however when it is true it is usually far less dramatic (e.g. for scalar types).

Even with move semantics available, passing this parameter by value can be expensive. Consider for example vector<vector<int>>:

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

In the pass-by-value case, x is copied once to the parameter of resize. And then internally, since the code can not know at compile time by how much resize is growing the vector, x is usually copied (not moved) a second time from resize's parameter into its proper place within the vector.

With pass-by-const-reference, the x in the above example need be copied only once. In this case, x has an expensive copy constructor and so any copies that can be saved represents a significant savings.

If we can be efficient for push_back, we should be efficient for resize as well. The resize taking a reference parameter has been coded and shipped in the CodeWarrior library with no reports of problems which I am aware of.

History
Date User Action Args
2010-10-21 18:28:33adminsetmessages: + msg3421
2007-06-11 00:00:00admincreate