void
void

Reputation: 11

C++ Reference of vector

class Refvect { public: vector &refv; Refvect(int t, vector &refv = vector()) : refv(refv) { }; void operator()() { refv.clear(); } }; int main () { Refvect r(0); r(); }

With Visual Studio 2010, this gives me an error : "vector iterators incompatible" at the execution, but I don't understand why (but I can insert elements in refv without any problem). The temporary object vector() lives as long as the reference, no?

Upvotes: 1

Views: 2363

Answers (2)

Daniel Earwicker
Daniel Earwicker

Reputation: 116664

The temporary object vector() lives as long as the reference, no?

No!

Temporaries destruct at the end of the outermost enclosing expression - i.e. an expression that is embedded in a statement rather than another expression. There is no magic tracking of references to ensure that objects live as long as references to them - that would be garbage collection.

Update:

In response to your comment:

if I use const vector<int> &refv; it works

I'm not sure how that could be. If you add const to the parameter refv then it is no longer compatible with the member and so should not compile. If you change the member to const also then you should find that you cannot call clear on it, because it that is not a const member function.

And if you've found something in C++ that "seems to work", then you're using C++ in completely the wrong way!

There a lots of ways for something to "seem to work" in C++ under highly specific special circumstances, but which will fail more obviously if those circumstances are altered. This is called "undefined behaviour" - the results may include apparent correct behaviour, sometimes.

The most common form is where data ceases to be valid even when there is still a means of accessing it, which is the situation you have here.

The correct way to use C++ is to thoroughly understand the limits of defined behaviour and stay well inside them, as far as you possibly can. In particular you need to understand how long objects live for, so you can ensure that references to objects don't live longer than the objects they refer to.

Upvotes: 1

sharptooth
sharptooth

Reputation: 170489

As soon as the statement

Refvect r(0);

is executed (control passes beyond the semicolon) the temporary vector<int> &refv = vector<int>() is destroyed. Now the reference stored inside the class object is dangling - not bound to any live object. Trying to access the object through such reference is undefined behavior.

Upvotes: 4

Related Questions