C++ 17: Deduce signature from Callable in a template

Viewed 340

If and how is it possible to deduce the signature type from any callable in C++17? Snippet:

template <typename T>
struct MyFunction;

template <typename R, typename... Args>
struct MyFunction<R(Args...)>
{
};

template <typename Callable>
auto deduceSignature(Callable&& c)
{
    // using Signature = ???;
    // return MyFunction<Signature>{ ???};}
}

I would like to use use class template argument deduction in the return statement. In client code I want to write this then:

std::int8_t freeFunction(std::int8_t x)
{
    return x;
}

auto c1 = deduceSignature(&freeFunction);
auto c2 = deduceSignature([](std::int8_t x){
    return x;
});
1 Answers

std::function can be constructed from any callable, and can deduce the signature (since c++17). We can use this to make a type trait that extracts the signature.

#include <functional>

template <typename T>
struct get_signature;

template <typename R, typename... Args>
struct get_signature<std::function<R(Args...)>> {
    using type = R(Args...);
};

template <typename Callable>
auto deduceSignature(Callable&& c)
{
    using Signature = typename get_signature<decltype(std::function{c})>::type;
}

int main() {
    deduceSignature([](int a){return 5;});
}
Related