STL containers' resize passes by value?

K

kfriddile

I'm working with a math library that uses some 16-byte-aligned types.
Under MSVC at least, alignment can't be specified for function
parameters. So, when I try to create a std::vector of one of these
types, I get a compilation error from vector::resize because it takes
the object by value like so:

void resize(size_type _Newsize, _Ty _Val)

but then just passes it as a const reference to an implementation
function. If i change the above to:

void resize(size_type _Newsize, const _Ty& _Val)

everything works fine. I believe passing by value is standard-
conformant, but I'm wondering what the rationale for that is?
 
J

James Kanze

I'm working with a math library that uses some 16-byte-aligned
types. Under MSVC at least, alignment can't be specified for
function parameters. So, when I try to create a std::vector
of one of these types, I get a compilation error from
vector::resize because it takes the object by value like so:
void resize(size_type _Newsize, _Ty _Val)
but then just passes it as a const reference to an
implementation function. If i change the above to:
void resize(size_type _Newsize, const _Ty& _Val)
everything works fine. I believe passing by value is
standard- conformant, but I'm wondering what the rationale for
that is?

To easily support things like:
v.resize( 100, v[ 0 ] ) ;
A naive implementation of resize would invalidate the reference
before using it. (But why the standard insists on supporting a
naive implementation, I don't know.)
 
H

Howard Hinnant

I'm working with a math library that uses some 16-byte-aligned
types.  Under MSVC at least, alignment can't be specified for
function parameters.  So, when I try to create a std::vector
of one of these types, I get a compilation error from
vector::resize because it takes the object by value like so:
     void resize(size_type _Newsize, _Ty _Val)
but then just passes it as a const reference to an
implementation function.  If i change the above to:
     void resize(size_type _Newsize, const _Ty& _Val)
everything works fine.  I believe passing by value is
standard- conformant, but I'm wondering what the rationale for
that is?

To easily support things like:
    v.resize( 100, v[ 0 ] ) ;
A naive implementation of resize would invalidate the reference
before using it.  (But why the standard insists on supporting a
naive implementation, I don't know.)

James is correct that this *is* the rationale the committee used in
deciding upon the pass-by-value signature for resize. However the
rationale itself is in error. A v.resize(N, v) never invalidates v
(prior to constructing from it) whether or not the resize causes
an internal reallocation.

1. If there is no internal reallocation, v is simply appended to
the end of the vector.
2. If there is an internal reallocation, the new buffer can be (and
typically is) completely constructed, including the new elements at
the end, before the old buffer is destroyed.

The only tricky self-referencing case within vector is v.insert
(iterator i, v[j]) when i references a location prior to v[j], and
when there is sufficient capacity. v[j] /must/ be relocated (and
overwritten) -- to make room for the new element(s) -- prior to
inserting those new elements. Ironically the signature for v.insert
is:

iterator insert(iterator position, const T& x);

:)

But implementors endeavor to get the self-referencing case correct
anyway.

Fwiw, the current C++0X draft has:

requires AllocatableElement<Alloc, T>
void resize(size_type sz);
requires AllocatableElement<Alloc, T, const T&>
void resize(size_type sz, const T& c);

-Howard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top