Date: Wed, 14 Jan 2026 12:54:34 +0000
Actually to get the absolute perfect solution, it's more complicated than:
if ( decltype(auto) x = Func() ) return static_cast<decltype(x)>(x);
And I'll explain why. In the above line of code, let's say that
'Func()' is 'expr'. So we have:
if ( decltype(auto) x = expr ) return static_cast<decltype(x)>(x);
Now let's consider all of the things that 'expr' could be:
1) PRvalue (i.e. T)
2) Xvalue (i.e. a R-value reference, i.e T&&)
3) Lvalue (i.e. T&)
We accommodate these three things. But there's a fourth thing:
4) A local variable which is of non-reference type
If 'expr' is a local variable of non-reference type, then "return
expr" could result in Named Return Value Optimisation (NRVO). We don't
want to scupper this optimisation.
Therefore the prefect solution might be something like:
constexpr bool nrvo = __builtin_is_local_variable( expr ); //
'expr' is not evaluated in this context
if constexpr ( nrvo )
{
if ( expr ) return expr;
}
else
{
if ( decltype(auto) x = expr ) return static_cast<decltype(x)>(x);
}
Actually it might be even more complicated than that if we want NRVO
on the 'x' variable too:
constexpr bool nrvo = __builtin_is_local_variable( expr ); //
'expr' is not evaluated in this context
if constexpr ( nrvo )
{
if ( expr ) return expr;
}
else if constexpr ( __builtin_is_reference_type(expr) ) // 'expr'
is not evaluated in this context
{
if ( decltype(auto) x = expr ) return static_cast<decltype(x)>(x);
}
else
{
// Here 'expr' is a PRvalue, so hopefully we can get NRVO on
the local variable 'x'
if ( auto x = expr ) return x;
}
if ( decltype(auto) x = Func() ) return static_cast<decltype(x)>(x);
And I'll explain why. In the above line of code, let's say that
'Func()' is 'expr'. So we have:
if ( decltype(auto) x = expr ) return static_cast<decltype(x)>(x);
Now let's consider all of the things that 'expr' could be:
1) PRvalue (i.e. T)
2) Xvalue (i.e. a R-value reference, i.e T&&)
3) Lvalue (i.e. T&)
We accommodate these three things. But there's a fourth thing:
4) A local variable which is of non-reference type
If 'expr' is a local variable of non-reference type, then "return
expr" could result in Named Return Value Optimisation (NRVO). We don't
want to scupper this optimisation.
Therefore the prefect solution might be something like:
constexpr bool nrvo = __builtin_is_local_variable( expr ); //
'expr' is not evaluated in this context
if constexpr ( nrvo )
{
if ( expr ) return expr;
}
else
{
if ( decltype(auto) x = expr ) return static_cast<decltype(x)>(x);
}
Actually it might be even more complicated than that if we want NRVO
on the 'x' variable too:
constexpr bool nrvo = __builtin_is_local_variable( expr ); //
'expr' is not evaluated in this context
if constexpr ( nrvo )
{
if ( expr ) return expr;
}
else if constexpr ( __builtin_is_reference_type(expr) ) // 'expr'
is not evaluated in this context
{
if ( decltype(auto) x = expr ) return static_cast<decltype(x)>(x);
}
else
{
// Here 'expr' is a PRvalue, so hopefully we can get NRVO on
the local variable 'x'
if ( auto x = expr ) return x;
}
Received on 2026-01-14 12:54:46
