class Refvect { public: vector &refv; Refvec开发者_运维知识库t(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?
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.
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.
精彩评论