Reputation: 1045
Playing around with the source code from Dangerous implicit conversion in emplace I detected the following behavior:
struct Foo
{
public:
explicit Foo(const int& i) : i(i) {
cout << "explicit int ctor called" << endl; }
explicit Foo(const double& x) : i(i) {
cout << " explicit double ctor called // i : " << i << endl; }
Foo(int&&) = delete;
Foo(double&&) = delete;
void foo() const {
cout << i << endl; }
private:
const int& i;
};
void bar(const double& d) {
cout << "---------- create object vector ------------" << endl;
std::vector<Foo> fv;
fv.emplace_back(d);
fv[0].foo();
cout << "---------- create object default ------------" << endl;
Foo f(d);
f.foo();
}
int main(){
bar(5.0);
return 0;
}
Prints:
---------- create object vector ------------
explicit double ctor called // i : 5
0
---------- create object default ------------
explicit double ctor called // i : 5
5
Thus in both cases the reference member gets correctly initialized during object creation, indicated by the outputs i = 1
. But after calling the foo()
function on both objects they yield different results. Retrieving the recently emplaced Object from the vector prints 0
even thought it should print 1
. The other object performs right.
Question Why is the value of the const reference member not persistent when emplaced in the STL container ? (I am not interested in advices like "simply do not use (const) references as class members.)
Upvotes: 0
Views: 766
Reputation: 141628
On this line:
explicit Foo(const double& x) : i(i) {
The member reference i
is initialized with itself, which causes undefined behaviour.
Upvotes: 1