template function as template parameter, what is the standard?
-
Wednesday, July 18, 2012 4:44 PM
Suppose you have the following code
emplate<typename T,void (T::*m)(int)> struct B{ void f(T* a,int x){ (a->*m)(x); } }; struct A{ template<typename X> void f(int){ } void wrap(int i){ f<char>(i); } B<A,&A::f<char> > y; }; int main(){ A a; }
This definition
B<A,&A::f<char> > y;
works with gcc,but not with Visual studio 2010:
error C2440: 'specialization' : cannot convert from 'overloaded-function' to 'void (__thiscall A::* )(int)'
On the contrary,
B<A,&f<char> > y;
works with visual studio but not with gcc.
Note that B<A,&A::f<char> > y; placed in the main works for VS as well.
IS B<A,&f<char> > y; not standard? is there a way (apart wrapping the template function) to make the thing compile with both compilers?
All Replies
-
Wednesday, July 18, 2012 5:16 PM
On 7/18/2012 12:44 PM, Fabio DallaLibera wrote:
This definition
B<A,&A::f<char> > y;
works with gcc,but not with Visual studio 2010:
error C2440: 'specialization' : cannot convert from 'overloaded-function' to 'void (__thiscall A::* )(int)'
On the contrary,
B<A,&f<char> > y;
works with visual studio but not with gcc.GCC is right, VC is wrong.
IS B<A,&f<char> > y; not standard?
It is not. The only way to form a pointer-to-member is &ClassName::MemberName. The standard is very clear about it:
5.3.1p4 A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses. [ Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is &unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. —end note ]
is there a way (apart wrapping the template function) to make the thing compile with both compilers?
Macros and #ifdef's, I suppose.
Igor Tandetnik
- Marked As Answer by Fabio DallaLibera Thursday, July 19, 2012 4:55 AM
-
Thursday, July 19, 2012 7:03 AM
Thank you, I resorted to
#ifdef _WIN32
#define vsFix(a,b) b
#else
#define vsFix(a,b) a::b
#endif
B<A,&vsFix(A,f)<char> > y; -
Thursday, July 19, 2012 12:02 PM
Fabio DallaLibera wrote:
Thank you, I resorted to
#ifdef _WIN32_MSC_VER might be a better choice:
http://msdn.microsoft.com/en-us/library/b0084kay.aspx
Igor Tandetnik

