Home > Back-end >  How to make proxying const/ref/volatile qualification without duplication in C ?
How to make proxying const/ref/volatile qualification without duplication in C ?

Time:03-23

Say I want to write some "proxy" object for a callable, e.g. to add some feature that happens before the wrapped callable is invoked. Further, say I want to be const-correct, so that the proxy has an accessible non-const operator() only if the wrapped callable does. Then I need to do something like this, defining two versions of the operator and using SFINAE:

template <typename F>
struct Proxy {
  F wrapped;
  
  template <typename = std::enable_if_t<std::is_invocable_v<F&>>>
  auto operator()();
  
  template <typename = std::enable_if_t<std::is_invocable_v<const F&>>>
  auto operator()() const;
};

This is annoying enough, but if I also want to proxy ref qualifications now I need for overloads, which is really getting excessive. Heaven help me if I also want to proxy volatile qualfiication.

Is there a shortcut to make this less awful? I seem to recall there was at least a feature proposed for addition to the standard.

CodePudding user response:

The proposed feature I was thinking of was P0847R7 ("Deducing this"), which was accepted for C 23. There are some useful slides here. I don't have a compiler to check this with, but I believe my four operators could be written as one with something like the following:

template <typename F>
struct Proxy {
  F wrapped;
  
  template <typename Me>
      requires std::invocable<std::like_t<Me, F>>
  auto operator()(this Me&& me);
};

(The type requirement here uses the hypothetical like_t metafunction assumed by P0847R7. See this question.)

  • Related