I would like to return multiple values and declare that function using auto
.
But that does not work well. Values can not be returned correctly. It was overwritten.
I try to execute following functions f1
~f3
. Those function should return vector and string in tuple.
But only f3
works well.
#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;
}
You can also execute this program at online compiler wandbox from this link.
f1()
causes an segmentation fault.f2()
returns wrong values in std::vector
. It seems random number.f3()
returns all values correctly.Why does this problem occur?
Is it impossible to return multiple values and declare that function using auto
?
The problem occurs because std::forward_as_tuple
returns references to local variables - the return type is tuple<vector<double>&,string&>
.
The first two functions produce undefined behaviour.
The third one works because you explicitly return by value, although the forwarding doesn't work because you did not move the l-values so they get copied into the returned tuple.
The correct way to return a tuple is just:
return std::tuple{std::move(vec),std::move(str)};