Ссылка на элемент вектора, возвращаемый функцией в 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
С статической продолжительностью хранения или любым другое дело, и это не продлит жизнь.