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

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

本文遵循“署名-非商业用途-保持一致”创作公用协议
 
gcc 4.7.3 不支持成员函数模板特化。如下代码:
 
  1. #ifndef __MEMFUNTEMPLATE_H__
  2. #define __MEMFUNTEMPLATE_H__
  3.  
  4. #include <stdio.h>
  5.  
  6. class Base {};
  7. class Derived : public Base {};
  8.  
  9. struct Functor {
  10. template <typename T> void function() {
  11. printf(" Primary template....\n");
  12. }
  13.  
  14. template<>
  15. void function<int>(){
  16. printf(" Specialization for int....\n");
  17. }
  18.  
  19. template<> void function<Base *>() {
  20. printf(" Specialization for Base *....\n");
  21. }
  22. };
  23.  
  24. class Tester {
  25. public:
  26. static void DoTest()
  27. {
  28. Functor functor;
  29. functor.function<char>();
  30. functor.function<int>();
  31. functor.function<Base *>();
  32. functor.function<Derived *>();
  33. }
  34. };
  35.  
  36. #endif // __MEMFUNTEMPLATE_H__

在 VS2010 中编译运行是没有问题的,但在 gcc 4.7.3下,编译都通不过:

  1. ../src/MemFunTemplate.h:21:14: error: explicit specialization in non-namespace scope struct Functor
  2. ../src/MemFunTemplate.h:22:24: error: template-id function<int> in declaration of primary template
  3. ../src/MemFunTemplate.h:26:14: error: explicit specialization in non-namespace scope struct Functor
  4. ../src/MemFunTemplate.h:26:38: error: template-id function<Base*>’ in declaration of primary template
  5. ../src/MemFunTemplate.h:26:21: error: void Functor::function()’ cannot be overloaded
  6. ../src/MemFunTemplate.h:22:10: error: with void Functor::function()’
  7. ../src/MemFunTemplate.cpp: In function int main()’:
  8. ../src/MemFunTemplate.cpp:17:2: error: DoTest is not a member of Functor

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

  1. /*
  2. * MemFunTemplate.h
  3. *
  4. * Created on: Jul 12, 2013
  5. * Author: http://blog.csdn.net/kesalin/
  6. */
  7.  
  8. #ifndef MEMFUNTEMPLATE_H_
  9. #define MEMFUNTEMPLATE_H_
  10.  
  11. #include <stdio.h>
  12.  
  13. template<typename T>
  14. struct DummyIdentity {
  15. typedef T type;
  16. };
  17.  
  18. class Base {};
  19. class Derived : public Base {};
  20.  
  21. struct Functor {
  22. template <typename T> void function() {
  23. function(DummyIdentity<T>());
  24. }
  25.  
  26. private:
  27.  
  28. template <typename T>
  29. void function(DummyIdentity<T>) {
  30. printf(" Primary template DummyIdentity<T>....\n");
  31. }
  32.  
  33. void function(DummyIdentity<int>) {
  34. printf(" overload function for DummyIdentity<int>....\n");
  35. }
  36.  
  37. void function(DummyIdentity<Base *>) {
  38. printf(" overload function for DummyIdentity<Base *>....\n");
  39. }
  40. };
  41.  
  42. class Tester {
  43. public:
  44. static void DoTest()
  45. {
  46. Functor functor;
  47. functor.function<char>();
  48. functor.function<int>();
  49. functor.function<Base *>();
  50. functor.function<Derived *>();
  51. }
  52. };
  53.  
  54. #endif /* MEMFUNTEMPLATE_H_ */

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

  1. Primary template DummyIdentity<T>....
  2. overload function for DummyIdentity<int>....
  3. overload function for DummyIdentity<Base *>....
  4. Primary template DummyIdentity<T>....

注意:

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

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

 

让gcc支持成员函数模板的trick的更多相关文章

  1. 函数模板的trick

    函数模板的trick 让gcc支持成员函数模板的trick 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循“署名-非商业用途-保持一致”创作公用协议   gcc ...

  2. 读书笔记 effective c++ Item 45 使用成员函数模板来接受“所有兼容类型”

    智能指针的行为像是指针,但是没有提供加的功能.例如,Item 13中解释了如何使用标准auto_ptr和tr1::shared_ptr指针在正确的时间自动删除堆上的资源.STL容器中的迭代器基本上都是 ...

  3. Effective C++ -----条款45:运用成员函数模板接受所有兼容类型

    请使用member function templates(成员函数模板)生成”可接受所有兼容类型“的函数. 如果你声明member templates 用于“泛化copy构造”或“泛化assignme ...

  4. 读书笔记_Effective_C++_条款四十五:运用成员函数模板接受所有兼容类型

    比如有一个Base类和一个Derived类,像下面这样: class BaseClass {…}; class DerivedClass : public BaseClass {…}; 因为是父类与子 ...

  5. C++程序设计方法4:成员函数模板

    成员函数的模板: 普通类的成员函数,也可以定义为函数模板,如: class normal_class { public: int value; template<typename T> v ...

  6. [EffectiveC++]item45:运用成员函数模板接受所有兼容类型

  7. C++ - 模板类模板成员函数(member function template)隐式处理(implicit)变化

    模板类模板成员函数(member function template)隐式处理(implicit)变化 本文地址: http://blog.csdn.net/caroline_wendy/articl ...

  8. C++模板编程中只特化模板类的一个成员函数

    模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数.类模板中大多数成员函数的功能可能是一模一样的,特化时我们可能只需要重新实现1.2个成员函数即可.在这种情况下,如果全 ...

  9. C++模板编程中只特化模板类的一个成员函数(花样特化一个成员函数)

    转自:https://www.cnblogs.com/zhoug2020/p/6581477.html 模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数.类模板中大多 ...

随机推荐

  1. 浅谈SDN和NFV之间的关系

    一个行业固定设备的折旧周期很长,任何变革的发生都绝非易事,但是网络却一次性面临两项革新--软件定义网络(SDN)和网络功能虚拟化(NFV),在变革网络的过程中,二者若想取得成功可能会依赖彼此的技术,或 ...

  2. js 常见混乱

    slice(begin.end) 复制出一个新的数组或是一个新的字符串,其中end 不包括end本身 splice(begin,howmany,item1....itemn) 更改原先的array 会 ...

  3. 移动web前端小结(一)--摘自小鹿_同学

    一.框架 框架:Bootstrap+HTML5 Boilerplate. 两个框架整合到一起可以看一下这位大神的文章:<使用 Bootstrap 和 HTML5 Boilerplate 开始一个 ...

  4. STM32之独立看门狗与窗口看门狗总结

    一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...

  5. Java 第8章 循环结构进阶

    循环结构进阶 什么是二重循环? 二重循环的执行顺序是什么?

  6. Android 时间维护服务 TimeService(针对于特殊定制设备)

    此方法针对于无法自动获取网络时间的特殊设备,正常 Android 设备直接调用 System.currentTimeMillis(); 方法获取当前时间即可. TimeService 集成于 Serv ...

  7. 阿里云RDS for MySQL备份文件+binlog恢复过程中碰到的一些问题

    1.一开始通过官方下载有的压缩包安装,碰到各种依赖问题,最后采用YUM安装 1.通过yum安装percona-Xtrabackup 1.1 先安装依赖: yum install perl-DBI yu ...

  8. C#中SQL Server数据库连接池使用及连接字符串部分关键字使用说明

    (1) 数据库的连接使用后,必须采用close()连接等效的方法关闭连接.只有关闭后,连接才能进入连接池. 参见微软的使用连接池说明:https://msdn.microsoft.com/zh-cn/ ...

  9. 解决Ubuntu下Chrome浏览器网页中文字体混乱

    在Ubuntu下使用Chrome浏览器时碰到了网页中文字体混乱的现象: 黑体和楷体混杂,看起来非常不美观. 这是由于许多网页并没有指定字体,然后浏览器将调用系统默认字体配置. 首先,安装文泉驿字体: ...

  10. java-注解

    概念 Annontation是Java5开始引入的新特征.中文名称一般叫注解.它提供了一种安全的类似注释的机制,用来将任何的信息或元数据与程序元素(类.方法.成员变量等)进行关联.更通俗的意思是为程序 ...