如何在 C++ 中不重复地进行代理 const/ref/volatile 限定?
How to make proxying const/ref/volatile qualification without duplication in C++?
假设我想为可调用对象编写一些“代理”对象,例如添加一些在调用包装的可调用对象之前发生的功能。此外,假设我想成为 const-correct,以便代理只有在包装的可调用文件存在时才具有可访问的非 const operator()
。然后我需要做这样的事情,定义两个版本的运算符并使用 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;
};
这已经够烦人的了,但如果我现在还想代理 ref 资格,我需要重载,这真的太过分了。我也想代理volatile
资格
求大神帮帮我
有没有捷径可以让事情变得不那么糟糕?我似乎记得至少有人建议将一项功能添加到标准中。
我考虑的提议功能是 P0847R7 ("Deducing this
"), which was accepted for C++23. There are some useful slides here。我没有编译器来检查这一点,但我相信我的四个运算符可以写成一个,如下所示:
template <typename F>
struct Proxy {
F wrapped;
template <typename Me>
requires std::invocable<std::like_t<Me, F>>
auto operator()(this Me&& me);
};
(这里的类型要求使用假设的like_t
metafunction assumed by P0847R7. See 。)
假设我想为可调用对象编写一些“代理”对象,例如添加一些在调用包装的可调用对象之前发生的功能。此外,假设我想成为 const-correct,以便代理只有在包装的可调用文件存在时才具有可访问的非 const operator()
。然后我需要做这样的事情,定义两个版本的运算符并使用 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;
};
这已经够烦人的了,但如果我现在还想代理 ref 资格,我需要重载,这真的太过分了。我也想代理volatile
资格
有没有捷径可以让事情变得不那么糟糕?我似乎记得至少有人建议将一项功能添加到标准中。
我考虑的提议功能是 P0847R7 ("Deducing this
"), which was accepted for C++23. There are some useful slides here。我没有编译器来检查这一点,但我相信我的四个运算符可以写成一个,如下所示:
template <typename F>
struct Proxy {
F wrapped;
template <typename Me>
requires std::invocable<std::like_t<Me, F>>
auto operator()(this Me&& me);
};
(这里的类型要求使用假设的like_t
metafunction assumed by P0847R7. See