You can only pass constants to template parameters. This means only Data types (including classes), const variables, and pure numbers/macros that define numbers.
Was hoping someone would have a good answer for this - after a quick look I wasn't able to definitively figure it out either. FWIW, on gcc 3.4.3, even the line mem_ptr<target, 0> mp; fails to compile. I believe the compiler has special logic to initialize a member function pointer with integer '0', which is in general is not legal due to the difference in size between the 2 data types. Maybe the logic to handle this only works for normal initialization, but fails when used in the context of a constant template parameter (although in your case, VC++ is allowing the explicit value 0, but not the default param, which is odd).
Looking at the spec, it seems like both should be legal, based on 4.11:
A null pointer constant (4.10) can be converted to a pointer to member type; the result is the null member pointer
value of that type and is distinguishable from any pointer to member not created from a null pointer constant. Two null
member pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to
member of cv-qualified type is a single
I've submitted this as a bug report to the VC++ team.
It seems hard to see how this can be anything BUT a compiler bug. I've tried using (void*)(0) as the default, and even (void (T::*)())(0) and they don't work either.
Looks like g++ has something similar. Maybe this could be submitted there too.
jsmith:
I'm aware of the boost solution, and am in fact using it for the case in quesiton. It has some benifits and some detrements, but I won't go into those here.