Я хотел бы вернуть несколько значений и объявить эту функцию с помощью auto.
Но это плохо работает. Значения не могут быть возвращены правильно. Он был перезаписан.
Я пытаюсь выполнить следующие функции f1~f3. Эти функции должны возвращать вектор и строку в кортеже.
Но хорошо работает только f3.
#include <iostream>
#include <vector>
#include <string>
#include <tuple>
auto f1(){
std::vector<double> v(10, 0);
std::string s = "hello";
return std::forward_as_tuple(v, s);
}
auto f2(){
std::vector<double> v(10, 0);
return std::forward_as_tuple(v, "hello");
}
std::tuple<std::vector<double>, std::string> f3(){
std::vector<double> v(10, 0);
std::string s = "hello";
return std::forward_as_tuple(v, s);
}
int main(void){
//change the function
//auto [vec, str] = f1();
//auto [vec, str] = f2();
auto [vec, str] = f2();
for (auto e : vec){
std::cout << "vec : " << e << std::endl;
}
std::cout << "str : " << str << std::endl;
}
Вы также можете выполнить эту программу в онлайн-компиляторе wandbox по этой ссылке.
f1() вызывает ошибку сегментации.f2() возвращает неверные значения в std::vector. Кажется, случайное число.f3() корректно возвращает все значения.Почему возникает эта проблема?
Нельзя ли вернуть несколько значений и объявить эту функцию с помощью auto?
-> return std::make_tuple(std::move(v), std::move(s));.





Проблема возникает из-за того, что std::forward_as_tuple возвращает ссылки на локальные переменные — тип возвращаемого значения — tuple<vector<double>&,string&>.
Первые две функции производят неопределенное поведение.
Третий работает, потому что вы явно возвращаете по значению, хотя переадресация не работает, потому что вы не переместили l-значения, чтобы они копировались в возвращаемый кортеж.
Правильный способ вернуть кортеж:
return std::tuple{std::move(vec),std::move(str)};
В третьем форвард работает, но он лишний, потому что значения копируются.
@Eljay Достаточно честно, я хотел сказать, что это не работает так, как предполагалось OP, потому что пересылка l-значений приводит к копиям вместо перемещений.
Цитируя cppreference.com: «Создает кортеж ссылок на аргументы» (выделено мной). Вы возвращаете висячие ссылки.