Ссылка на элемент вектора, возвращаемый функцией в C++

может ли кто-нибудь проверить, что следующее является ошибкой, и объяснить почему? Я думаю, что знаю, но неясны детали. (Моя фактическая проблема включала вектор перечислений, а не ints, но я не думаю, что это должно иметь значение.) Предположим, у меня есть следующий код:

std::vector<int> f (void) {
  std::vector<int> v;
  v.push_back(5);
  return v;
}

void g (void) {
  const int &myIntRef = f()[0];
  std::cout << myIntRef << std::endl;
}

Я прав, что myIntRef немедленно является висящей ссылкой, потому что возвращаемое значение f нигде не сохраняется в стеке?

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

  const int myIntCopy = f()[0];  // copy, not a reference

другими словами, является ли возвращаемый результат f () отброшенным до того, как можно скопировать 0-й элемент?

2 ответов


Да, это действительно неправильно. Когда вы звоните:

return v;

временная копия объекта v создается и

const int &myIntRef = f()[0];

инициализирует вашу ссылку с первым элементом этой временной копии. После этой строки временная копия больше не существует, что означает, что myIntRef является недопустимой ссылкой, использование которой производит неопределенное поведение.

что вы должны сделать, это:

std::vector<int> myVector = f();
const int &myIntRef = myVector[0];
std::cout << myIntRef << std::endl;

который (Спасибо к копировать elision) использует оператор присваивания для инициализации


это ошибка. В конце полного выражения const int &myIntRef = f()[0]; временный вектор будет уничтожен, а память освобождена. Любое последующее использование myIntRef - это неопределенное поведение.

при некоторых обстоятельствах привязка ссылки на временное может продлить срок службы временного. Это не один из таких случаев, компилятор не знает, возвращена ли ссылка std::vector<int>::operator[] является частью временного или ссылки на int С статической продолжительностью хранения или любым другое дело, и это не продлит жизнь.