Background
I have a series of lambdas that perform different checks on the captured variables and return std::nullopt if the check failed. return std::nullopt is the first return statement. Then, if the check succeeded, they go on and compute the value.
Problem
The types of return expressions are not consistent, e.g. std::nullopt_t cannot be converted to std::optional<T>, even though the other way around works. In particular, I'd like the following code to compile and run, printing 2:
#include <functional>
#include <utility>
#include <optional>
int x = 3;
auto lambda = [](){
if (x == 2)
return std::nullopt;
return std::optional(2);
};
#include <iostream>
int main () {
using return_type = std::invoke_result_t<decltype(lambda)>;
static_assert(std::is_same<return_type, std::optional<int>>{},
"return type is still std::nullopt_t");
std::cout << lambda().value() << '\n';
}
Thoughts
I believe that I need to use std::common_type<Args...> somewhere, but I can neither enforce presence of it or deduce Args, as it might require language support.
Instead of using template type deduction to infer the return type of the lambda, why not explicitly specify that return type?
std::common_typeis commonly with templates, which you don't have.