On Sunday, March 24, 2024, Jason McKesson wrote:
Use an explicit deduction guide:
```
template<typename T>
lock_guard(T &&arg) -> lock_guard<std::remove_cvref_t<T>>;
```
Thanks for that. I'm typing on my phone here so I can't test this out properly, but it looks like I'll be able to replace my function-and-class with the following standalone class followed by an explicit deduction guide:
namespace std {
template<typename F_ref, typename... Params_refs>
class elide final {
using R = invoke_result_t< F_ref, Params_refs... >;
static_assert( is_same_v< R, remove_reference_t<R> > ); // To ensure F returns by value
using F = remove_reference_t<F_ref>;
F &&f; // 'f' is always an Rvalue reference
tuple< Params_refs... > const args_tuple; // just a tuple full of references
public:
template<typename F, typename... Params>
explicit elide(F &&arg, Params&&... args) noexcept
: f( move(arg) ),
args_tuple( static_cast<Params_refs>(args)... ) {}
operator R(void) noexcept(noexcept(apply(static_cast<F_ref>(f),move(args_tuple))))
{
return apply( static_cast<F_ref>(f), move(args_tuple) );
}
};
template<typename F, typename... Params>
elide(F&&,Params&&...) -> elide<F&&,Params&&...>;
}