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.)