I am trying to manipulate the std::optional
using container like std::vector
.
I started by doing the code below :
#include <iostream>
#include <vector>
#include <string>
#include <optional>
using namespace std;
using optional_vecs = std::optional<std::vector<std::string>>;
optional_vecs returnStrings()
{
optional_vecs myVect(std::in_place);
myVect->emplace_back("Name");
return myVect;
}
int main()
{
for (auto e : returnStrings().value())
std::cout << e << " ";
return 0;
}
The problem here is that I get nothing in the output: I guess that because std::optional::value
return a reference as in my case it is a reference to a temporary.
So to resolve that I tried to use std::reference_wrapper
as below :
using optional_vecs = std::optional<std::reference_wrapper<std::vector<std::string>>>;
optional_vecs returnStrings()
{
optional_vecs myVect;
myVect->get().emplace_back("Name");
return myVect;
}
Now I got a crash and an error :
for-range
loop saying the range for loop requires a suitable "begin" function and none was found.
The code below works but I don't like to declare a variable and then calli the Value():
int main()
{
auto result = returnStrings();
for (auto e : result.value())
std::cout << e << " ";
return 0;
}
So how could I return an std::optional holding a std::vector
in the way functionName().Value()
.
Your issue here in the first two cases is that since returnStrings()
returns a temporary, the for loop will not extend its life unless you actually capture what it returns. Capturing result.value()
doesn't do you any good since it will not extend the lifetime of returnStrings()
.
So how could I return an std::optional holding a std::vector in the way
functionName().Value()
.
You have to capture the return of functionName()
. You can do what you did, or in C++20 you can use the new init-statement version of ranged for which was built for cases like this and would look like
for (auto&& opt_vec = returnStrings(); auto e : opt_vec.value())
std::cout << e << " ";