I have a template function that should take a function pointer and arguments, then invoke the function pointer with the given arguments (let's call it `Invoke`). However, when I call the template function with an overloaded function as an argument, template deduction fails.

I have used enable\_if so that only one overload would be valid, but this didn't help.

```cpp
#include <string>
#include <type_traits>

void foo(int, int){}
void foo(std::string, std::string) {}

template <bool Val1, bool Val2, bool ...Rest>
struct And
{
    enum {value = And<Val1 && Val2, Rest...>::value};
};
template <bool Val1, bool Val2>
struct And<Val1, Val2>
{
    enum {value = Val1 && Val2};
};

template <typename ...Params, typename ...Args, typename = typename std::enable_if<
    And<std::is_convertible<Args, Params>::value...>::value
>::type>
void Invoke(void (*fn)(Params...), Args ...args){}

int main() {
    Invoke(&foo, "a", "b");
    return 0;
}

```

Try on [ideone](https://ideone.com/Httn9G).

The compiler complains that `mismatched argument pack lengths while expanding ‘std::is_convertible<Args, Params>::value’`, when both overloads are present.
When I comment out the `int` overload, the program compiles just fine, and when I comment out the `std::string` overload, deduction fails as it should, since `const char[]` is not implicitly convertible to `int`.

The standard (section 17.8.2.1.6.2 of the C++17 standard) says the following:

> 
> If the argument is an overload set (not containing function templates), trial argument deduction is
>  attempted using each of the members of the set. If deduction succeeds for only one of the overload set
>  members, that member is used as the argument value for the deduction. If deduction succeeds for more
>  than one member of the overload set the parameter is treated as a non-deduced context.
> 
> 
> 

So I would expect that the compiler would try the `int` overload, where deduction would fail. When it tries the `std::string` overload, the deduction would succeed.

Since the deduction would succeed for only one of the overload set members, I would expect that it would then proceed as if the `int` overload didn't exist, and the compilation would succeed like it does when the other overload is commented out, but it fails.

Where am I wrong?

References to standard will be appreciated.