I'm trying to iterate over a std::vector<X>
contained in a struct T
that I access through a std::optional<T>
. Contrary to my expectations, the behavior is different if I first store the std::optional<T>
into a copy versus if I iterate it directly:
#include <optional>
#include <string>
#include <vector>
// The rest is the same in both implementations
struct Object
{
std::string id;
std::vector<SomeStructType> items;
};
Object readDataFile() { /*....*/ return {}; }
bool dataFileExists() { /*....*/ return true; }
std::optional<Object> getData()
{
if (!dataFileExists()) {
return std::nullopt;
}
Object obj = readDataFile();
return obj;
}
int main()
{
// Implementation 1 - works
auto items = getData().value().items;
for (auto const& item : items)
{
// will normally iterate over items
}
// Implementation 2 - for loop is skipped
for (auto const& item : getData().value().items)
{
// this body will never execute
}
}
I would expect those two to behave the same. Why does implementation 2 skip the for loop? `
The file read is the same in both cases, with items.size() == 1
. I omitted some other nullopt
checks and asserts in the provided code, but I don't expect them to be relevant.