#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;
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdm9pZCBmb28oaW50LCBpbnQpe30Kdm9pZCBmb28oc3RkOjpzdHJpbmcsIHN0ZDo6c3RyaW5nKSB7fQoKdGVtcGxhdGUgPGJvb2wgVmFsMSwgYm9vbCBWYWwyLCBib29sIC4uLlJlc3Q+CnN0cnVjdCBBbmQKewoJZW51bSB7dmFsdWUgPSBBbmQ8VmFsMSAmJiBWYWwyLCBSZXN0Li4uPjo6dmFsdWV9Owp9Owp0ZW1wbGF0ZSA8Ym9vbCBWYWwxLCBib29sIFZhbDI+CnN0cnVjdCBBbmQ8VmFsMSwgVmFsMj4KewoJZW51bSB7dmFsdWUgPSBWYWwxICYmIFZhbDJ9Owp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIC4uLlBhcmFtcywgdHlwZW5hbWUgLi4uQXJncywgdHlwZW5hbWUgPSB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwKCUFuZDxzdGQ6OmlzX2NvbnZlcnRpYmxlPEFyZ3MsIFBhcmFtcz46OnZhbHVlLi4uPjo6dmFsdWUKPjo6dHlwZT4Kdm9pZCBJbnZva2Uodm9pZCAoKmZuKShQYXJhbXMuLi4pLCBBcmdzIC4uLmFyZ3Mpe30KCmludCBtYWluKCkgewoJSW52b2tlKCZmb28sICJhIiwgImIiKTsKCXJldHVybiAwOwp9
prog.cpp: In function ‘int main()’:
prog.cpp:24:23: error: no matching function for call to ‘Invoke(<unresolved overloaded function type>, const char [2], const char [2])’
Invoke(&foo, "a", "b");
^
prog.cpp:21:6: note: candidate: template<class ... Params, class ... Args, class> void Invoke(void (*)(Params ...), Args ...)
void Invoke(void (*fn)(Params...), Args ...args){}
^~~~~~
prog.cpp:21:6: note: template argument deduction/substitution failed:
prog.cpp:18:49: error: mismatched argument pack lengths while expanding ‘std::is_convertible<Args, Params>::value’
template <typename ...Params, typename ...Args, typename = typename std::enable_if<
^~~~~~~~