zoukankan      html  css  js  c++  java
  • 让gcc支持成员函数模板的trick

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

    #include <stdio.h>

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

    struct Functor {
        template <typename T> void function() {
            printf(" Primary template. ");
        }

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

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

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

    #endif // __MEMFUNTEMPLATE_H__
    在 VS2010 中编译运行是没有问题的,但在 gcc 4.7.3下,编译都通不过:
    ../src/MemFunTemplate.h:21:14: error: <strong>explicit specialization in non-namespace scope</strong> ‘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<Base*>’ 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 <stdio.h>
    template<typename T>
    struct DummyIdentity {
        typedef T type;
    };
    class Base {};
    class Derived : public Base {};
    struct Functor {
        template <typename T> void function() {
            function(DummyIdentity<T>());
        }
    private:
        template <typename T>
        void function(DummyIdentity<T>) {
            printf(" Primary template DummyIdentity<T>. ");
        }
        void function(DummyIdentity<int>) {
            printf(" overload function for DummyIdentity<int>. ");
        }
        void function(DummyIdentity<Base *>) {
            printf(" overload function for DummyIdentity<Base *>. ");
        }
    };
    class Tester {
    public:
        static void DoTest()
        {
            Functor functor;
            functor.function<char>();
            functor.function<int>();
            functor.function<Base *>();
            functor.function<Derived *>();
        }
    };
    #endif /* MEMFUNTEMPLATE_H_ */


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

     Primary template DummyIdentity<T>.
     overload function for DummyIdentity<int>.
     overload function for DummyIdentity<Base *>.
     Primary template DummyIdentity<T>.


    注意:

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

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

     
  • 相关阅读:
    ajax01
    django04
    数据库
    WeakHashMap类
    IdentityHashMap
    Hashtable类
    LinkedHashMap类
    HashMap和TreeMap类
    PriorityQueue
    Synchronized
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318869.html
Copyright © 2011-2022 走看看