It is known that template arguments can be pointers to member functions.
So I can write:
struct Bar
{
int fun(float x);
};
template <int (Bar::*FUN)(float)>
struct Foo
{ /*...*/ };
typedef Foo<&Bar::fun> FooBar;
But what if I want the the Bar type itself to be a template argument:
template <typename B, int (B::*FUN)(float)>
struct Foo
{ /*...*/ };
typedef Foo<Bar, &Bar::fun> FooBar;
Now, when I use it, I have to write Bar twice!
My question is: Is there a way to force the compiler to deduce the class type automatically?
The objective is for this to just work:
typedef Foo<&Bar::fun> FooBar;
typedef Foo<&Moo::fun> FooMoo;
You probably should just write the class name in there. However, if you really want to avoid that you can use the evil magic of macros. The simple version is more dangerous:
This will accept any kind of non-type template parameter, and you may encounter hard-to-understand errors if the
Fooimplementation only works with pointers-to-member.To make it a bit safer you need a metafunction that tells you the class name:
Also both of these use C++11 so they won’t work with old compilers. This simple version can be rewritten to use the old
typeofor similar compiler extensions. Rewriting the safer version requires simulating variadic templates.