3

I want to be able to call a function with a template parameter that is of function type (including parameter and return types), i.e. double(int, long), and in the function separate the types and use them individually.

For example I want to be able to call a function

printRes<double(int, long)>();

This function above should parse the template argument and extract the return type double and output it.

I know how to do this using a class and variadic templates:

#include <iostream>
#include <typeinfo>

template <typename T>
class A {};

template <typename Res, typename... Args>
class A<Res (Args...)> { // Parse template argument
public:
    void printRes() {
        std::cout << typeid(Res).name() << std::endl;
    }
};

Then I can use it like this:

int main() {
    A<double(int, long)> a;
    a.printRes();
}

Which outputs:

d

I want to do this using a simple function instead. This is what I came up with:

template <typename Res, typename... Args>
void printRes() {
    std::cout << typeid(Res).name() << std::endl;
}

However, now I must specify the template parameters like this instead:

int main() {
    printRes<double, int, long>();
}

Is there any way to implement the function so it can be called using the same template parameter as the class-version (i.e. double(int, long))?

Felix Glas
  • 15,065
  • 7
  • 53
  • 82

1 Answers1

3

I guess you are almost there. You can use your trait inside a function template. Here is a possible implementation:

#include <iostream>
#include <typeinfo>

template <typename T>
struct A { };

template<typename Res, typename... Args>
struct A<Res (Args...)> 
{
    using type = Res;
};

template<typename T>
void printRes() 
{
    using Res = typename A<T>::type;
    std::cout << typeid(Res).name() << std::endl;
}

int main()
{
    printRes<double(int, long)>();
}

And here is a live example.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • Thanks, this solves my problem. Can't believe I didn't think of using a class to get the type. I still wonder why it's not possible to parse the template arguments for functions as it's possible with classes though. – Felix Glas Mar 09 '13 at 19:41