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

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -