Why member functions cannot be used as template arguments? For example, I want to do like:
struct Foo {
void Bar() { // do something
}
};
template &
They can be used as non-type parameters, but you need to use the right syntax
struct Foo {
void Bar() { // do something
}
};
template <typename TOwner, void(TOwner::*func)()>
void Call(TOwner *p) {
(p->*func)();
}
int main() {
Foo a;
Call<Foo, &Foo::Bar>(&a);
return 0;
}
In fact, member-function pointers can be used as template arguments (just exactly as any other pointer type may be used as template parameter):
struct A
{
int f(float x);
};
template <int (A::F*)(float)>
struct B {};
template<A *> struct C;
template<A &> struct D;
However, according to the following excerpt from the C++ standard, one cannot pass references to members.
[temp.param]
- A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
(4.1) — integral or enumeration type,
(4.2) — pointer to object or pointer to function,
(4.3) — lvalue reference to object or lvalue reference to function,
(4.4) — pointer to member,
(4.5) — std::nullptr_t.
Next, given you managed to pass your function type somehow and want to call it inside, you encounter the same problem as if you want to store them inside a function pointer or a std::function object: namely to call you need both, the member function as well as the concrete object. Passing only the function won't suffice.
But in fact you can achieve what you want. Just bind the function to your object and pass it afterwards:
template<typename T, typename F>
void call(T&& t, F&&f)
{
f(std::forward<T>(t));
}
struct A
{
void foo() { std::cout<<"hello"<<std::endl; }
};
int main()
{
A a;
auto f=std::bind(&A::foo, a); //or possibly "std::ref(a)" instead of "a"
call(3,f);
}
DEMO