template function as template parameter, what is the standard?

Answered template function as template parameter, what is the standard?

  • Wednesday, July 18, 2012 4:44 PM
     
      Has Code

    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
     
     Answered

    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

  • Thursday, July 19, 2012 7:03 AM
     
      Has Code

    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