2017-01-21 1 views
0

Игра вокруг с исходным кодом из Dangerous implicit conversion in emplace я обнаружил следующее поведение:Назначение `сопзЬ члена reference` в явном Конструктор не является постоянным использованием` станд :: VECTOR`

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; 
} 

распечаток:

---------- create object vector ------------ 
explicit double ctor called // i : 5 
0 
---------- create object default ------------ 
explicit double ctor called // i : 5 
5 

Таким образом, в обоих случаях опорный элемент получает правильную инициализацию при создании объекта, обозначенную выводом i = 1. Но после вызова функции foo() на обоих объектах они дают разные результаты. Извлечение недавно установленного объекта из векторных отпечатков 0 даже считалось, что он должен печатать 1. Другой объект работает правильно.

Вопрос Почему значение константного опорного элемента не сохраняется, когда внедрившийся в контейнере STL? (Я не заинтересован в советах, как «просто не использует (константные) ссылки в качестве членов класса.)

+0

Потому что:..? неопределенное поведение –

+0

нормально, почему для меня это выглядит как действительный C++ – SebNag

+1

'Foo :: i' является оборванной ссылкой –

ответ

1

На этой линии:.

explicit Foo(const double& x) : i(i) { 

элемента опорного i инициализируются с собой, что causes undefined behaviour

Смежные вопросы