clickMe
clickMe

Reputation: 1045

Assignment of `const reference` member in explicit Constructor is not persistent using `std::vector`

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

Answers (1)

M.M
M.M

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

Related Questions