zoukankan      html  css  js  c++  java
  • 函数模板的trick

    函数模板的trick

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

    罗朝辉 (http://www.cnblogs.com/kesalin/)

    本文遵循“署名-非商业用途-保持一致”创作公用协议
     
    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> ‘structFunctor’
    ../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>)了。

     
     
     
    分类: C/C++
    标签: C++gcctemplate
  • 相关阅读:
    《小团团团队》第一次作业:团队亮相
    《代码敲不队》第六次作业:团队项目系统设计改进与详细设计
    《代码敲不队》第五次作业:项目需求分析改进与系统设计
    《代码敲不队》第四次作业:项目需求调研与分析
    《代码敲不队》第三次作业:团队项目的原型设计
    《代码敲不队》第二次作业:团队项目选题报告
    《代码敲不队》第一次作业:团队亮相
    《队长说得队》第六次作业:团队项目系统设计改进与详细设计
    《队长说得队》第五次作业:项目需求分析改进与系统设计
    《队长说得队》第四次作业:项目需求调研与分析
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3187838.html
Copyright © 2011-2022 走看看