让gcc支持成员函数模板的trick

gcc 4.7.3 不支持成员函数模板特化。如下代码:
#ifndef __MEMFUNTEMPLATE_H__
#define  __MEMFUNTEMPLATE_H__

#include 

class  Base {};
class  Derived :  public  Base {};

struct  Functor {
    template   void  function() {
        printf(" Primary template .\n");
    }

    template<>
     void  function< int >(){
        printf(" Specialization for int .\n");
    }

    template<>  void  function() {
        printf(" Specialization for Base * .\n");
    }
};

class  Tester {
public :
     static   void  DoTest()
    {
        Functor functor;
        functor.function< char >();
        functor.function< int >();
        functor.function();
        functor.function();
    }
};

#endif   //  __MEMFUNTEMPLATE_H__
在 VS2010 中编译运行是没有问题的,但在 gcc 4.7.3下,编译都通不过:
../src/MemFunTemplate.h:21:14: error:  explicit specialization  in non- namespace scope ‘ struct Functor’
../src/MemFunTemplate.h:22:24: error: template-id ‘function< int>’  in declaration of primary template
../src/MemFunTemplate.h:26:14: error:  explicit specialization  in non- namespace scope ‘ struct Functor’
../src/MemFunTemplate.h:26:38: error: template-id ‘function’  in declaration of primary template
../src/MemFunTemplate.h:26:21: error: ‘ void Functor::function()’ cannot be overloaded
../src/MemFunTemplate.h:22:10: error: with ‘ void Functor::function()’
../src/MemFunTemplate.cpp: In function ‘ int main()’:
../src/MemFunTemplate.cpp:17:2: error: ‘DoTest’  is not a member of ‘Functor’


为了达到近似成员函数模板特化的效果,可以利用成员函数主模板以及重载函数来实现:


/*
 * MemFunTemplate.h
 *
 *  Created on: Jul 12, 2013
 *      Author:  http://blog.csdn.net/kesalin/
 */

#ifndef MEMFUNTEMPLATE_H_
#define  MEMFUNTEMPLATE_H_
#include 
template
struct  DummyIdentity {
    typedef T type;
};
class  Base {};
class  Derived : public  Base {};
struct  Functor {
    template   void  function() {
        function(DummyIdentity());
    }
private :
    template 
     void  function(DummyIdentity) {
        printf(" Primary template DummyIdentity .\n");
    }
     void  function(DummyIdentity< int >) {
        printf(" overload function for DummyIdentity .\n");
    }
     void  function(DummyIdentity) {
        printf(" overload function for DummyIdentity .\n");
    }
};
class  Tester {
public :
     static   void  DoTest()
    {
        Functor functor;
        functor.function< char >();
        functor.function< int >();
        functor.function();
        functor.function();
    }
};
#endif  /* MEMFUNTEMPLATE_H_ */


调用 DoTest() 运行结果如下:

 Primary template DummyIdentity .
 overload function  for DummyIdentity< int> .
 overload function  for DummyIdentity .
 Primary template DummyIdentity .


注意:

VS2010 版本的代码,模板形参为 T,在实例化不会进行隐式类型转换。即用 Derived * 当作实参调用的是主模板,而不是 Base * 特化版本

而在 gcc  下,模板形参虽然也为T,但影响重载决议的 function 参数为:DummyIdentity,用不同的实际参数实例化该模板,得到的是一堆重载函数。因此用 Derived * 当作实参时,调用的函数自然就是实例化的 void function(DummyIdentity)了。

 

你可能感兴趣的:(让gcc支持成员函数模板的trick)