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&&...>;