Generic Member Function Pointer as a Template Parameter

generic member function pointer as a template parameter

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);

How to pass non-static member function pointer to a template function in C++?

Non-static member functions have an implicit parameter of the class type as the first parameter of the function, and it is that object which is mapped to the this pointer. That means that you need to pass an object of the class type as the first argument after the member function pointer like

<< getExecutionTime(&Obj::testFunc, obj, uniform_dist(rng), i) << std::endl;

or you can use a lambda instead like

<< getExecutionTime([&](){ obj.testFunc(uniform_dist(rng), i); }) << std::endl;

Neat way to parametrize function template with generic function pointer

In order to get

foo<bar1>();

You need template<auto> from C++17. That would look like

int bar1() { return 1; }
double bar2() { return 2.0; }

template<auto function> void foo() { std::cout << function() << "\n"; }

int main()
{
foo<bar1>();
foo<bar2>();
}

Which outputs

1
2

Live Example

Before C++17 you have to specify the type as there is no auto deduction of the type of a non type template parameters.

Passing member function pointer as template parameter

template<typename F>
void call_func(F func) {
(wrapped.*func)();
}

then call like this:

wr.call_func(&some_class::some_func);

If you want to use the return value too, you'll need this:

template<typename F>
auto call_func(F func) -> decltype((std::declval<T>().*func)()) {
return (wrapped.*func)();
}

If you have C++14, you can omit the -> decltype(...) part and use decltype(auto) as the return value.

If you also want to pass functions, you can use variadic templates and forwarding for that.

template<typename F, typename... Args>
decltype(auto) call_func(F func, Args&&... args) {
return (wrapped.*func)(std::forward<Args>(args)...);
}

Generic member function pointer as template parameter inside another class

Either change Args&& to Args& in the definition of addMF or change val to move(val) when you invoke it.

Generic member function pointer

You could create a generic templated function which accepts the signature you are interested in, pass in the instance of the object and the pointer to the member function. For example:

template<typename T>
void CallObjectMethod(int(T::*func)(int), T& obj, int val)
{
cout << (obj.*func)(val);
}

Now to call it like you mentioned in your example:

X x, x1;
CallObjectMethod(&X::echoX, x, 10);
CallObjectMethod(&X::echoX, x1, 20);

For object Y you could do something like:

Y y, y1;
CallObjectMethod(&Y::echoY, y, 10);
CallObjectMethod(&Y::echoY, y1, 20);

Generic 'member function' wrapper for other member function(s)?

Since you're using C++17, you can use auto on template parameters:

template<auto f, typename... Args>
void Dispatch(Args... args) {
//...

And invoke them normally by passing a pointer to member function as template argument #1. Live Example.

If you need to check whether f is a pointer to member function of that class, you can use some static_assert statements before invoking (this->*f)(args...).

And a small thing: if you're using rvalue semantics, it's also a good idea to receive Args&&and use std::forward.



Related Topics



Leave a reply



Submit