Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

generic member function pointer as a template parameter

Consider this code:

#include <iostream> using namespace std;  class hello{ public:     void f(){         cout<<"f"<<endl;     }     virtual void ff(){         cout<<"ff"<<endl;     } };  #define call_mem_fn(object, ptr)  ((object).*(ptr))  template<R (C::*ptr_to_mem)(Args...)> void proxycall(C& obj){     cout<<"hello"<<endl;     call_mem_fn(obj, ptr_to_mem)(); }  int main(){     hello obj;     proxycall<&hello::f>(obj); } 

Of course this won't compile at line 16, because the compiler doesn't know what R, C and Args, are. But there's another problem: if one tries to define those template parameters right before ptr_to_mem, he runs into this bad situation:

template<typename R, typename C, typename... Args, R (C::*ptr_to_mem)(Args...)>                               //  ^variadic template, but not as last parameter! void proxycall(C& obj){     cout<<"hello"<<endl;     call_mem_fn(obj, ptr_to_mem)(); }  int main(){     hello obj;     proxycall<void, hello, &hello::f>(obj); } 

Surprisingly, g++ does not complain about Args not being the last parameter in the template list, but anyway it cannot bind proxycall to the right template function, and just notes that it's a possible candidate.

Any solution? My last resort is to pass the member function pointer as an argument, but if I could pass it as a template parameter it would fit better with the rest of my code.

EDIT: as some have pointed out, the example seems pointless because proxycall isn't going to pass any argument. This is not true in the actual code I'm working on: the arguments are fetched with some template tricks from a Lua stack. But that part of the code is irrelevant to the question, and rather lengthy, so I won't paste it here.

like image 784
Lorenzo Pistone Avatar asked Mar 19 '12 22:03

Lorenzo Pistone


People also ask

Can a member function be a template?

Member functions can be function templates in several contexts. All functions of class templates are generic but are not referred to as member templates or member function templates. If these member functions take their own template arguments, they are considered to be member function templates.

Can a template parameter be a function?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

What can be a template parameter?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

Can we pass Nontype parameters to templates?

Template non-type arguments in C++It is also possible to use non-type arguments (basic/derived data types) i.e., in addition to the type argument T, it can also use other arguments such as strings, function names, constant expressions, and built-in data types.


1 Answers

You could try something like this:

template <typename T, typename R, typename ...Args> R proxycall(T & obj, R (T::*mf)(Args...), Args &&... args) {     return (obj.*mf)(std::forward<Args>(args)...); } 

Usage: proxycall(obj, &hello::f);

Alternatively, to make the PTMF into a template argument, try specialization:

template <typename T, T> struct proxy;  template <typename T, typename R, typename ...Args, R (T::*mf)(Args...)> struct proxy<R (T::*)(Args...), mf> {     static R call(T & obj, Args &&... args)     {         return (obj.*mf)(std::forward<Args>(args)...);     } }; 

Usage:

hello obj;  proxy<void(hello::*)(), &hello::f>::call(obj);  // or  typedef proxy<void(hello::*)(), &hello::f> hello_proxy; hello_proxy::call(obj); 
like image 192
Kerrek SB Avatar answered Oct 17 '22 08:10

Kerrek SB