Проблема в том, что ссылка создана с использованием rvalue вместо lvalue? - PullRequest
0 голосов
/ 07 марта 2020

Я хотел бы понять проблему со следующим кодом. Он компилируется, но не работает должным образом.

#include <iostream>
#include <vector>

class A
{
  public:
    std::vector<int> getVector() { return m_vector; }
    std::vector<int> m_vector = {1, 2, 3};
};

int main()
{
    A objA;

    for(int i = 0; i < objA.getVector().size(); i++)
    {
         int &item = objA.getVector().at(i);
         std::cout << "\nvector item: " << item;
    }

    return 0;
}

Вывод:

  • векторный элемент: 0
  • векторный элемент: 0
  • векторный элемент: 3

Ожидаемый результат:

  • векторный элемент: 1
  • векторный элемент: 2
  • векторный элемент: 3

Я понимаю, что нет необходимости объявлять элемент как ссылку, но я хотел бы понять проблему, которая возникает после этого таким образом.

Я думаю, что проблема в том, что элемент ссылки ожидает lvalue, а метод std :: vector :: at возвращает ссылку. Поскольку возвращаемый тип метода std :: vector :: at равен int & , компиляция не выдает никакой ошибки, но тогда результат не соответствует ожидаемому.

Можно ли подтвердить, что это проблема, и я больше ничего не пропускаю?

1 Ответ

3 голосов
/ 07 марта 2020

getVector() возвращает значение std::vector. Поэтому objA.getVector().at(i) вызывает .at(i) для временного объекта.

.at возвращает ссылку на элемент в данной позиции. int &item привязан к этому ссылочному элементу временного объекта .

После строки

int &item = objA.getVector().at(i);

временный std::vector уничтожен и вместе с ним элемент что item ссылается.

Таким образом, использование этой ссылки затем в

std::cout << "\nvector item: " << item;

вызывает неопределенное поведение, поскольку объект, на который ссылался item, больше не существует.

Это может быть исправлено путем возврата по ссылке из getVector, в этом случае item будет ссылаться на элемент в std::vector элементе objA, а не на его временную копию.

...