Coalescing lvalue references to std-optionals I want to coalesce (lvalue references to) optionals of the same type, in C++17:

#include &lt;optional&gt;

template &lt;typename... Ts&gt;
constexpr auto coalesce(std::optional&lt;Ts&gt;&amp;... optionals );

template &lt;typename T&gt;
constexpr std::optional&lt;T&gt;&amp; coalesce(std::optional&lt;T&gt;&amp; x, std::optional&lt;T&gt;&amp; y)
{
    return x.has_value() ? x : y;
}

template &lt;typename T&gt;
constexpr std::optional&lt;T&gt; coalesce(std::optional&lt;T&gt;&amp; x)
{
    return x;
}

template &lt;typename T, typename... Ts&gt;
constexpr std::optional&lt;T&gt; coalesce(std::optional&lt;T&gt;&amp; x, std::optional&lt;Ts&gt;&amp;... xs )
{
    return coalesce(x, coalesce(std::forward&lt;std::optional&lt;T&gt;&amp;&gt;(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.
So ideally you want to write something like:

template &lt;typename... Ts&gt;
constepxr auto coalesce(std::optional&lt;Ts&gt;&amp;... xs)
{
   return (xs || ...);
}


But the issue here is of course that it will convert the optionals to bool before applying the boolean or-operator. You could however cast it to a type that does provide the right semantics for the boolean or-operator to do the thing you want:

template &lt;typename T&gt;
struct coalescable {
    T &amp;x;
    coalescable(T &amp;x_): x(x_) {}
    constexpr const coalescable &amp;operator||(const coalescable &amp;other) {
        return x.has_value() ? *this : other;
    }
};


And then use that in the fold expression:

template &lt;typename... Ts&gt;
constepxr auto coalesce(std::optional&lt;Ts&gt;&amp;... xs)
{
   return (coalescable(xs) || ...).x;
}