• 让gcc支持成员函数模板的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: 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<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>)了。

     
  • 相关阅读:
    UnknownHostException: xxx,使用nacos远程调用服务(负载均衡)报错
    Failed to bind properties under 'logging.level' to java.util.Map<java.lang.String, java.lang.String>日志级别的问题
    JS 如何返回到父页面?多重跳转之后返回到初始页(父页面)?或者说返回父页面的父页面?
    绝对路径${pageContext.request.contextPath}用法及其与web.xml中Servlet的url-pattern匹配过程
    VS在release模式下进行调试
    visual studio 运行找不到dll库
    C++ 字符串格式化
    SWIG使用遇到的问题
    其他技术---域名中转
    mongoDB增删改查(命令行操作数据库)
  • 原文地址:https://www.cnblogs.com/kesalin/p/member_funtion_template.html
Copyright © 2020-2023  润新知