I want to coalesce (lvalue references to) optionals of the same type, in C++17:
#include <optional>
template <typename... Ts>
constexpr auto coalesce(std::optional<Ts>&... optionals );
template <typename T>
constexpr std::optional<T>& coalesce(std::optional<T>& x, std::optional<T>& y)
{
return x.has_value() ? x : y;
}
template <typename T>
constexpr std::optional<T> coalesce(std::optional<T>& x)
{
return x;
}
template <typename T, typename... Ts>
constexpr std::optional<T> coalesce(std::optional<T>& x, std::optional<Ts>&... xs )
{
return coalesce(x, coalesce(std::forward<std::optional<T>&>(xs)...));
}
This is sub-optimal, as it uses recursive templated function calls, rather than ellipsis-based expansion in a single body. What would you suggest?
Notes:
- C++17 and no fancy libraries please.
- This can be seen as a specific case of the "return first parameter in a pack satisfying a predicate", with the predicate being
[](auto x) { return x.has_value(); }
- If possible, let's not copy any
T
's.