mardi 2 octobre 2018

Deducing function overload in a templated function

I'm writing my own std::async analogue (has to work back to Intel13/gcc 4.4 STL), and this works fine:

template <typename Func, typename ...Args>
struct return_value {
    template <typename T>
    using decayed = typename std::decay<T>::type;
    using type    = typename std::result_of<decayed<Func>(decayed<Args>...)>::type;
};

template <typename Func, typename ...Args>
typename return_value<Func,Args...>::type async(Func &&func, Args&&... args) {
    return func(args...);
}

void run(int a, double b) { 
    printf("a: %i  b: %f\n", a, b);
}

int main() {
    async(run, 1, 3.14);
}

But if I add an overload for run:

void run() {
    printf("no args\n");
}

Then it can't properly resolve:

<source>: In function 'int main()':
<source>:27:23: error: no matching function for call to 'async(<unresolved overloaded function type>, int, double)'
     async(run, 1, 3.14);
                       ^
<source>:14:43: note: candidate: 'template<class Func, class ... Args> typename return_value<Func, Args>::type async(Func&&, Args&& ...)'
 typename return_value<Func,Args...>::type async(Func &&func, Args&&... args) {
                                           ^~~~~
<source>:14:43: note:   template argument deduction/substitution failed:
<source>:27:23: note:   couldn't deduce template parameter 'Func'
     async(run, 1, 3.14);
                       ^
Compiler returned: 1

How can I take a function as a template parameter and properly deduce the overload given the arguments?

Aucun commentaire:

Enregistrer un commentaire