简体   繁体   中英

Decomposing C++17 function-like object in generic fashion?

In C++17 suppose I have a function-like object passed as a parameter to some template:

 template<typename F>
 void g(F f) {
    auto x = f(/*...*/);
 }

There are lots of different types F could be, such as a function pointer, a std::function, a lambda expression, and in fact any class type that implements operator() .

Is there any way to get the function-like objects arity and type of its parameters and the type of its return type?

I mean, ultimately F could be a class that overloads operator() with multiple different member functions, each with different arities, parameter types and return types - so there isn't a fully-general answer (unless there is some way to iterate that overload set, which I don't think there is).

But for the typical case where a function call expression involving f results in a single overload, is there a solution?

(also if there is any progress in C++20, worth mentioning too)

C++17's adds deduction guides for std::function , which we can use to do the deduce the function signature of non-overloaded function-like objects:

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

If you only wanted the return type, you could just use:

using result_type = typename decltype(std::function(f))::result_type;

If you want to avoid std::function altogether because of the compile-time costs, you can implement your own version of the deduction guides for your own type (possibly as general as a function_traits type trait). A sketch of how you might implement the deduction guides yourself can be seen in my answer here: https://stackoverflow.com/a/66038056/1896169

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM