Reputation: 2557
#include <iostream>
#include <vector>
struct MyClass{
const std::vector<float>::iterator& begin(){
return myvec.begin();
}
const std::vector<float>::iterator& end(){
return myvec.end();
}
std::vector<float> myvec;
};
int main(){
std::vector<float> mainvec(8,0);
MyClass myClass;
myClass.myvec = mainvec;
for (std::vector<float>::iterator it = myClass.begin();
it != myClass.end();++it){
std::cout << *it << " " ;
}
std::cout << std::endl;
}
In this code I get the following output:
0 0 0 0 0 0 0 0
#include <iostream>
#include <vector>
struct MyClass{
const std::vector<float>::iterator& begin(){
return myvec.begin();
}
const std::vector<float>::iterator& end(){
return myvec.end();
}
std::vector<float> myvec;
};
int main(){
std::vector<float> mainvec(8,0);
MyClass myClass;
myClass.myvec = mainvec;
const std::vector<float>::iterator& end_reference = myClass.end();
for (std::vector<float>::iterator it = myClass.begin();
it != end_reference;++it){
std::cout << *it << " " ;
}
std::cout << std::endl;
}
In this code I get the following output:
"empty output"
It has the problem in which I invoke (erroneously) the vector begin()
and end()
instead of MyClass methods.
I have the following minimal code to represent my doubt:
#include <iostream>
#include <vector>
struct MyClass{
const std::vector<float>::iterator& begin(){
return myvec.begin();
}
const std::vector<float>::iterator& end(){
return myvec.end();
}
std::vector<float> myvec;
};
int main(){
std::vector<float> mainvec(8,0);
MyClass myClass;
myClass.myvec = mainvec;
for (std::vector<float>::iterator it = myClass.myvec.begin();
it != myClass.myvec.end();++it){
std::cout << *it << " " ;
}
std::cout << std::endl;
}
I get the following warnings on lines 8 and 12:
returning reference to local temporary object [-Wreturn-stack-address] [cpp/gcc]
but when I compile and run the program, I get:
0 0 0 0 0 0 0 0
So, it seems that the local reference is not destroyed when it returns the myvec.begin()
. When I first wrote the code, I didn't thought it was going to be a problem, as in my head the begin() method from the vector would return a iterator reference to the first vector place, this iterator for me is not being allocated when I do myvec.begin(), but is a reference to this iterator. So, this warning shouldn't appear, as I am not allocating memory. But since I don't know how this mechanism works, I would like to learn it for writing consistent code. It seems that I can ignore this warning, can't I?
Upvotes: 4
Views: 3110
Reputation: 10917
std::vector::begin returns indeed a temporary object (see http://www.cplusplus.com/reference/vector/vector/begin/)
Your code is valid since you are binding the temporary object to a const reference (would not be legal with a non const reference), and copy it right away in a local variable it
.
edit: My mistake. This is indeed also UB to return a const reference from a temporary.
However assigning this reference to another const reference with a longer lifetime would result in undefined behavior as the lifetime of a temporary object is only extended to the lifetime of the const reference it is directly assigned to.
I would recommend taking into account the warning and return an iterator.
I also recommend reading http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
Upvotes: 2