vector.push_back - pushes values or references?

S

Siam

Hi,

I'm a little new to stl so bear with me...Say I have the following
code:

vector<int> vec;
int i = 3;
vec.push_back(i);
i=4;
cout<<vec.at(0)<<endl;

Looking at the signature of push_back, it seems to take a reference:

void push_back( const TYPE& val );

I wouldve thought that means the int i pass to the vector isn't
copied, but a reference to the original int is placed in the vector.
However, the above code returns 3, not 4, indicating the int has been
copied into the vector (on printing memory addresses, the ints are
stored in different memory addresses). My question is, why does the
push_back function take a reference, but yet still store a copy of the
object in the vector?

Cheers,

SR
 
J

Jim Langston

Siam said:
Hi,

I'm a little new to stl so bear with me...Say I have the following
code:

vector<int> vec;
int i = 3;
vec.push_back(i);
i=4;
cout<<vec.at(0)<<endl;

Looking at the signature of push_back, it seems to take a reference:

void push_back( const TYPE& val );

I wouldve thought that means the int i pass to the vector isn't
copied, but a reference to the original int is placed in the vector.
However, the above code returns 3, not 4, indicating the int has been
copied into the vector (on printing memory addresses, the ints are
stored in different memory addresses). My question is, why does the
push_back function take a reference, but yet still store a copy of the
object in the vector?

Cheers,

SR

..push_back() eventually uses the copy constructor of the object. So most
likly it accepts a reference, then calls the copy constructor on the
reference it has. Easy to determine this, just make a class with a private
copy constructor and try to make a vector out of it and use .push_back()
 
I

Ian Collins

Siam said:
Hi,

I'm a little new to stl so bear with me...Say I have the following
code:

vector<int> vec;
int i = 3;
vec.push_back(i);
i=4;
cout<<vec.at(0)<<endl;

Looking at the signature of push_back, it seems to take a reference:

void push_back( const TYPE& val );

I wouldve thought that means the int i pass to the vector isn't
copied, but a reference to the original int is placed in the vector.
However, the above code returns 3, not 4, indicating the int has been
copied into the vector (on printing memory addresses, the ints are
stored in different memory addresses). My question is, why does the
push_back function take a reference, but yet still store a copy of the
object in the vector?
Passing by reference insures only one copy of the object is made. If
the function used pass by value, the object would be copied twice.
 
I

Ian Collins

Ian said:
Passing by reference insures only one copy of the object is made. If
the function used pass by value, the object would be copied twice.
Oops, s/insures/ensures/ :)
 
A

Alf P. Steinbach

* Siam:
Hi,

I'm a little new to stl so bear with me...Say I have the following
code:

vector<int> vec;
int i = 3;
vec.push_back(i);
i=4;
cout<<vec.at(0)<<endl;

Looking at the signature of push_back, it seems to take a reference:

void push_back( const TYPE& val );

I wouldve thought that means the int i pass to the vector isn't
copied, but a reference to the original int is placed in the vector.
However, the above code returns 3, not 4, indicating the int has been
copied into the vector (on printing memory addresses, the ints are
stored in different memory addresses). My question is, why does the
push_back function take a reference, but yet still store a copy of the
object in the vector?

Because std::vector can be used for any copyable type, and for some
types an object may have a lot of data to be copied, and/or copying the
object may involve dynamic allocation, which is (relatively) slow.

The reference passing means that an object that is expensive to copy is
only copied once, namely when copied into the vector's storage.

It's not copied in the process of being passed as argument, because with
a reference argument and a resonable compiler all that's passed (if
anything is passed!) is the object's memory address.

Using 'T const&' (or equivalently 'const T&') is a very common idiom for
objects that may be expensive to copy.

E.g., instead of writing a formal argument as 'std::string s', you
should as a matter of course write 'std::string const& s', even if
std::string might be expected to be heavily optimized and perhaps
directly supported by the compiler.

Caveat: don't do that for function results, e.g. don't declare a
function as 'std::string const& foo()' instead of 'std::string foo()'.

Because that might result in a dangling reference (the referred to
object doesn't exist after the function call has returned) and thus most
probably Undefined Behavior where undesirable things may happen.

Hope this helps,

- Alf
 
P

Pete Becker

Siam said:
void push_back( const TYPE& val );

Maybe, but that's not required by the language definition. These things
are specified in a different way. The requirement is that
vec.push_back(object) puts a copy of object into vec. Passing by value
is okay, as is passing by const reference.
I wouldve thought that means the int i pass to the vector isn't
copied, but a reference to the original int is placed in the vector.
However, the above code returns 3, not 4, indicating the int has been
copied into the vector (on printing memory addresses, the ints are
stored in different memory addresses). My question is, why does the
push_back function take a reference, but yet still store a copy of the
object in the vector?

The reason for storing by value is that that's what the specification
says. <g> The design of STL assumes that objects are cheap to create and
to copy, so STL algorithms and containers deal with values, not
references. If you need reference semantics, use TR1's reference_wrapper
(also available from Boost), or use vector<TYPE*>. In both cases you
have to ensure that your objects hang around at least as long as the
container does. (For more details on reference_wrapper, see chapter 8 of
my book, "The Standard C++ Library Extension"; for details on TR1's
shared_ptr, see chapter 2).

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top