mercredi 1 avril 2020

Compiler unable to deduce template arguments for variadic template

Suppose I want to do partial function application to make a wide range of functions conform to a single signature.

For example, I could want to go from a double-parameter function to a single-parameter function as follows:

std::function<int(int, int)> doubleFoo = [](int i, int j) { return i + j; };
// Turn the function in a single-parameter function, using j = 5
std::function<int(int)> singleFoo = toSingleFoo(doubleFoo, 5);

As I want toSingleFoo to handle any single- or multi-argument function of which the first argument is an int, I've defined it as a variadic template function:

template <typename... Args>
std::function<int(int i)> toSingleFoo(std::function<int(int, Args&&...)> multiFoo, Args&&... args)
{
    // Changing the capture to [args...], [multiFoo, args], or [multiFoo, args...]
    // as suggested in a now-deleted answer, does not change the compiler error.
    auto singleFoo = [args](int i) { multiFoo(i, std::forward<Args>(args)...) };
    return singleFoo;
}

However, that gives the following compiler errors (using Visual Studio 2017, version 15.7.6):

error C2672: 'toSingleFoo': no matching overloaded function found
error C2784: 'std::function<int (int)> toSingleFoo(std::function<int(int,Args &&...)>,Args &&...)':
              could not deduce template argument for 'std::function<int(int,Args &&...)>' 
              from 'std::function<int (int,int)>'

Why is the compiler unable to deduce template arguments, despite an int being passed as second argument in the example above?

Aucun commentaire:

Enregistrer un commentaire