Intermediate Gotchas
The Default That Was Loaded Anyway
the optional with a value that still calls the fallback
std::string default_name() {
std::cout << "loading default\n";
return "Guest";
}
int main() {
std::optional<std::string> name = "Ada";
const std::string chosen = name.value_or(default_name());
std::cout << "name: " << chosen << '\n';
}
Does default_name run when name already contains "Ada"?
Why¶
value_or is an ordinary function call. C++ evaluates its argument, default_name(),
before entering that function, whether or not the optional already holds a value. The
function then returns the contained "Ada", so the eager fallback result is unused. A
conditional expression evaluates only its selected arm and is lazy in the way value_or
is not.
The fix¶
Takeaway: value_or(expr) receives an already-evaluated value; use a conditional
when producing the fallback is expensive or has effects.
Try it: g++ -std=c++17 main.cpp -o demo && ./demo