以通用方式分解C++17类函数对象?
在 C++17 中,假设我有一个类似函数的对象作为参数传递给某个模板:
template<typename F>
void g(F f) {
auto x = f(/*...*/);
}
F 可能有很多不同的类型,例如函数指针、std::function、lambda 表达式,实际上任何实现operator().
有什么方法可以获取类函数对象的参数类型和类型以及返回类型的类型吗?
我的意思是,最终 F 可能是一个重载operator()多个不同成员函数的类,每个成员函数都有不同的元数、参数类型和返回类型——所以没有一个完全通用的答案(除非有某种方法来迭代那个重载集,我认为没有)。
但是对于涉及 f 的函数调用表达式导致单个重载的典型情况,是否有解决方案?
(如果 C++20 有任何进展,也值得一提)
回答
C++17 为 增加了推导指南std::function,我们可以用它来推导非重载类函数对象的函数签名:
template <typename R, typename... Args>
constexpr auto do_something_with_the_signature(std::function<R(Args...)>) {
// Assuming that you only care about the return type.
// Otherwise, you may want some kind of wrapper to extract the signature to
// avoid runtime cost
}
...
using some_type_computation =
decltype(do_something_with_the_signature(std::function(f)));
如果您只想要返回类型,则可以使用:
using result_type = typename decltype(std::function(f))::result_type;
如果你想std::function完全避免因为编译时成本,你可以为你自己的类型实现你自己版本的推导指南(可能和function_traits类型特征一样通用)。您可以在我的回答中看到如何自己实施演绎指南的草图:https : //stackoverflow.com/a/66038056/1896169