Working with vectors

P

pmatos

Hi all,

I have a few question regarding standard C++ and the use of vectors.

Imagine:
void foo(vector<int> x);
vector<int> c;
vector<int> x;

----------

What happens when I do:
c = x;

and
foo(x);

Will it copy all x behind the scenes in both cases?

If so, then I wish this to be more efficient so I should probably pass
a reference right? How can I do this in both cases? In calling foo, how
can I make sure the body of foo won't try to change x? (probably const&
or &const, but I never know...)

Cheers,

Paulo Matos
 
R

Rolf Magnus

pmatos said:
Hi all,

I have a few question regarding standard C++ and the use of vectors.

Imagine:
void foo(vector<int> x);
vector<int> c;
vector<int> x;

----------

What happens when I do:
c = x;

and
foo(x);

Will it copy all x behind the scenes in both cases?
Yes.

If so, then I wish this to be more efficient so I should probably pass
a reference right?
Yes.

How can I do this in both cases?

For the first case, you can't unless you declare c as a reference to
vector said:
In calling foo, how can I make sure the body of foo won't try to change x?

Let it take a refernce to const vector said:
(probably const& or &const, but I never know...)

const vector<int>&. The & is always the last part.
 
C

Cy Edmunds

pmatos said:
Hi all,

I have a few question regarding standard C++ and the use of vectors.

Imagine:
void foo(vector<int> x);
vector<int> c;
vector<int> x;

----------

What happens when I do:
c = x;

and
foo(x);

Will it copy all x behind the scenes in both cases?

If so, then I wish this to be more efficient so I should probably pass
a reference right? How can I do this in both cases? In calling foo, how
can I make sure the body of foo won't try to change x? (probably const&
or &const, but I never know...)

Cheers,

Paulo Matos

What Rolf said. But I would add one more thing: if all you really need is a
sequence of values, consider writing foo
as

template <typename ITER>
foo(ITER first, ITER last);

Then you can call it with

foo(my_vector.begin(), my_vector.end());

but also

foo(my_list.begin(), my_list.end());

This technique is used extensively in the standard library (see <algorithms>
for instance) because it is both efficient and flexible.
 
D

davidrubin

Rolf said:
For the first case, you can't unless you declare c as a reference to
vector<int> and initialize it with c.

It's not that you can't. The copy constructor for std::vector already
takes a non-modifiable reference to the object being copied. So,

c = x;

calls 'c's copy constructor with a const reference to 'x'. 'x' is not
copied to a temporary, as is the case with 'foo'; only the value of 'x'
is copied to 'c'. The call is already as efficient as it can be.

/david
 
R

Rolf Magnus

It's not that you can't. The copy constructor for std::vector already
takes a non-modifiable reference to the object being copied. So,

c = x;

calls 'c's copy constructor with a const reference to 'x'.

Yes, and that will copy x to c. As I understood the OP, he wanted to get rid
of that copy. The only way to do that would be - as I mentioned - to make c
a reference to x instead of an own vector.
Anyway, it is very well possible that I misunderstood the OP here.
'x' is not copied to a temporary, as is the case with 'foo'; only the
value of 'x' is copied to 'c'. The call is already as efficient as it can
be.

That was actually my point.
 
K

Krishanu Debnath

(e-mail address removed) wrote:

[snip]
It's not that you can't. The copy constructor for std::vector already
takes a non-modifiable reference to the object being copied. So,

c = x;

calls 'c's copy constructor with a const reference to 'x'. 'x' is not
copied to a temporary, as is the case with 'foo'; only the value of 'x'
is copied to 'c'. The call is already as efficient as it can be.

/david

I could not make any sense out of your post. 'c = x; ' exactly calls
vector's assignment operator. If you want to avoid this 'copy' you need
to do what Rolf Magnus had suggested in his previous post.

Can you please elaborate more (optionally with an example) to prove your
point?

Thanks
Krishanu
 
D

davidrubin

Krishanu said:
(e-mail address removed) wrote:

[snip]
It's not that you can't. The copy constructor for std::vector already
takes a non-modifiable reference to the object being copied. So,

c = x;

calls 'c's copy constructor with a const reference to 'x'. 'x' is not
copied to a temporary, as is the case with 'foo'; only the value of 'x'
is copied to 'c'. The call is already as efficient as it can be.

/david

I could not make any sense out of your post. 'c = x; ' exactly calls
vector's assignment operator. If you want to avoid this 'copy' you need
to do what Rolf Magnus had suggested in his previous post.

Can you please elaborate more (optionally with an example) to prove your
point?

The question was:

What happens when I do:
c = x;

and
foo(x);

Will it copy all x behind the scenes in both cases?

My point is, no, 'x' will not be copied in both cases. In the case of
'c = x', 'x' is passed by const reference, whereas in the case of
'foo(x)', 'x' is passed by value, and hence is copied (to a temporary).

Given the context, I do not think OP's question was about how to avoid
copying 'x' altogether. However, you are correct to point out my error:
it is the assignment operator that is called, not the copy constructor.
/david
 
K

Krishanu Debnath

The question was:

What happens when I do:
c = x;

and
foo(x);

Will it copy all x behind the scenes in both cases?

My point is, no, 'x' will not be copied in both cases. In the case of
'c = x', 'x' is passed by const reference, whereas in the case of
'foo(x)', 'x' is passed by value, and hence is copied (to a temporary).

Makes much sense. Thanks for the clarification.

Krishanu
 
J

John Dibling

You could also templatize foo and pass iterators to the container,
rather than the container itself. Here's some psudocode to illustrate:

template<class iter> foo(iter itBegin, iter itEnd);

vector<int> c;
foo(c.begin(), c.end());

Take care,

John Dibling
 
P

pmatos

John said:
You could also templatize foo and pass iterators to the container,
rather than the container itself. Here's some psudocode to illustrate:

template<class iter> foo(iter itBegin, iter itEnd);

vector<int> c;
foo(c.begin(), c.end());

Take care,

John Dibling

Thanks for the suggestion. Will that work for constructors?

Cheers,

Paulo Matos
 

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

No members online now.

Forum statistics

Threads
474,206
Messages
2,571,069
Members
47,675
Latest member
RollandKna

Latest Threads

Top