c++ - Compilation issue with instantiating function template -
consider following code:
#include <iostream> struct s { void f(const char* s) { std::cout << s << '\n'; } }; template <typename... args, void(s::*mem_fn)(args...)> void invoke(s* pd, args... args) { (pd->*mem_fn)(args...); } int main() { s s; void(*pfn)(s*, const char*) = invoke<const char*, &s::f>; pfn(&s, "hello"); }
when compiling code, clang gives following error:
main.cpp:16:33: error: address of overloaded function 'invoke' not match required type 'void (s *, const char *)' void(*pfn)(s*, const char*) = invoke<const char*, &s::f> ^~~~~~~~~~~~~~~~~~~~~~~~~~ main.cpp:10:6: note: candidate template ignored: invalid explicitly-specified argument template parameter 'args' void invoke(s* pd, args... args) { ^ 1 error generated.
the message seems suggest template instantiation invoke<const char*, &s::f>
has failed. give me clues why this? believe has parameter pack.
your code ill-formed. mem_fn
in non-deduced context according [temp.deduct.type]:
the non-deduced contexts are:
— ...
— function parameter pack not occur @ end of parameter-declaration-list.
and [temp.param]:
a template parameter pack of function template shall not followed template parameter unless template parameter can deduced parameter-type-list of function template or has default argument (14.8.2). [ example:
template<class t1 = int, class t2> class b; // error // u can neither deduced parameter-type-list nor specified template<class... t, class... u> void f() { } // error template<class... t, class u> void g() { } // error
—end example ]
the mem_fn
argument in declaration:
template <typename... args, void(s::*mem_fn)(args...)> void invoke(s* pd, args... args) {
follows template parameter pack. cannot deduced list. could, however, pass argument:
template <typename... args> void invoke(s* pd, void(s::*mem_fn)(args...), args... args);
or wrap whole thing in struct don't need follow parameter pack template:
template <typename... args> struct invoke { template <void (s::*mem_fn)(args...)> static void invoke(s* pd, args... args); }; void(*pfn)(s*, const char*) = invoke<const char*>::invoke<&s::f>;
Comments
Post a Comment