Пожалуйста, обратите внимание на этот код. Я видел этот тип кода несколько раз. words
- локальный вектор. Как можно вернуть его из функции?
Можем ли мы гарантировать, что он не умрет?
std::vector<std::string> read_file(const std::string& path)
{
std::ifstream file("E:\\names.txt");
if (!file.is_open())
{
std::cerr << "Unable to open file" << "\n";
std::exit(-1);
}
std::vector<string> words;//this vector will be returned
std::string token;
while (std::getline(file, token, ','))
{
words.push_back(token);
}
return words;
}
std::vector<std::string>&
Ответы:
Пока ссылка не возвращается, это нормально.
words
будет перемещен в переменную, получающую результат.Локальная переменная выйдет за рамки. после того, как он был перемещен (или скопирован).
источник
До C ++ 11:
Функция вернет не локальную переменную, а ее копию. Однако ваш компилятор может выполнить оптимизацию, при которой фактическое действие копирования не выполняется.
См. Этот вопрос и ответ для получения дополнительной информации.
С ++ 11:
Функция переместит значение. См. Этот ответ для получения дополнительных сведений.
источник
Я думаю, вы имеете в виду проблему в C (и C ++), что возврат массива из функции недопустим (или, по крайней мере, не будет работать должным образом) - это потому, что возврат массива будет (если вы напишете его в простая форма) возвращают указатель на фактический массив в стеке, который затем сразу же удаляется при возврате функции.
Но в этом случае это работает, потому что
std::vector
это класс, а классы, как и структуры, могут (и будут) копироваться в контекст вызывающего. [На самом деле, большинство компиляторов оптимизируют этот конкретный тип копии, используя так называемую «оптимизацию возвращаемого значения», специально введенную, чтобы избежать копирования больших объектов, когда они возвращаются из функции, но это оптимизация, и с точки зрения программистов, это будет вести себя так, как если бы для объекта был вызван конструктор присваивания]Пока вы не возвращаете указатель или ссылку на что-то, что находится внутри возвращаемой функции, все в порядке.
источник
Чтобы хорошо понять поведение, вы можете запустить этот код:
Результат следующий:
Обратите внимание, что этот пример был предоставлен в контексте C ++ 03, его можно улучшить для C ++> = 11
источник
Я не согласен и не рекомендую возвращать
vector
:Это намного быстрее:
Я тестировал Visual Studio 2017 со следующими результатами в режиме выпуска:
8.01 MOP по ссылке
5.09 MOP, возвращающий вектор
В режиме отладки дела обстоят намного хуже:
0,053 MOPS по ссылке
0,034 MOP по вектору возврата
источник
На самом деле это провал дизайна. Вы не должны использовать возвращаемое значение для чего-либо, кроме примитивов, для чего-либо, что не является относительно тривиальным.
Идеальное решение должно быть реализовано через возвращаемый параметр с решением относительно ссылки / указателя и правильного использования «const \ 'y \' ness» в качестве дескриптора.
Кроме того, вы должны понимать, что метка на массиве в C и C ++ фактически является указателем, а его подписка фактически является символом смещения или сложения.
Таким образом, метка или ptr array_ptr === метка массива, возвращающая foo [смещение], на самом деле говорит о возвращаемом элементе в месте указателя памяти foo + смещение типа возвращаемого типа.
источник