The following code run fine but, for what I understand, it shouldn't
#include <iostream>
#include <vector>
struct Data
{
explicit Data():value(1){}
int value;
};
struct Foo
{
explicit Foo(Data& data):data_(data){}
inline void print() const
{
std::cout<<data_.value<<std::endl;
}
Data& data_;
};
void addEntry(std::vector<Foo>& vec)
{
Data data;
Foo foo(data);
vec.push_back(foo);
}
int main()
{
std::vector<Foo> vec;
addEntry(vec);
vec[0].print();
}
The function addEnty
create an instance of Data
called data
. Then creates an instance of Foo
, called foo
, which stores a reference to data
. This istance is then copyed inside the vector vec
. Therefore, when the function end, vec[0]
should contain a dangling reference since data
is destroyed. Am I right? So I would expect to obtain some garbage calling the method print()
. Is it only by chance that I obtain the right value 1 or am I missing something?
To make it correct, I would move data in order to avoid the dangling reference. So I would modify the constructor with
explicit Foo(Data&& data):data_(data){}
and the function with
Foo foo(std::move(data));
In this way foo
, and consequently its copy inside vec[0]
, contains the instance data
instead of a reference to it. Am I right? Is it the correct solution? In this way, Foo::data_
needs to be of type Data
or of type Data&
?