让gcc支持成员函数模板的trick
让gcc支持成员函数模板的trick
罗朝辉 (http://www.cnblogs.com/kesalin/)
- #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....\n");
- }
- template<>
- void function<int>(){
- printf(" Specialization for int....\n");
- }
- template<> void function<Base *>() {
- printf(" Specialization for Base *....\n");
- }
- };
- 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>....\n");
- }
- void function(DummyIdentity<int>) {
- printf(" overload function for DummyIdentity<int>....\n");
- }
- void function(DummyIdentity<Base *>) {
- printf(" overload function for DummyIdentity<Base *>....\n");
- }
- };
- 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>)了。
让gcc支持成员函数模板的trick的更多相关文章
- 函数模板的trick
函数模板的trick 让gcc支持成员函数模板的trick 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循“署名-非商业用途-保持一致”创作公用协议 gcc ...
- 读书笔记 effective c++ Item 45 使用成员函数模板来接受“所有兼容类型”
智能指针的行为像是指针,但是没有提供加的功能.例如,Item 13中解释了如何使用标准auto_ptr和tr1::shared_ptr指针在正确的时间自动删除堆上的资源.STL容器中的迭代器基本上都是 ...
- Effective C++ -----条款45:运用成员函数模板接受所有兼容类型
请使用member function templates(成员函数模板)生成”可接受所有兼容类型“的函数. 如果你声明member templates 用于“泛化copy构造”或“泛化assignme ...
- 读书笔记_Effective_C++_条款四十五:运用成员函数模板接受所有兼容类型
比如有一个Base类和一个Derived类,像下面这样: class BaseClass {…}; class DerivedClass : public BaseClass {…}; 因为是父类与子 ...
- C++程序设计方法4:成员函数模板
成员函数的模板: 普通类的成员函数,也可以定义为函数模板,如: class normal_class { public: int value; template<typename T> v ...
- [EffectiveC++]item45:运用成员函数模板接受所有兼容类型
- C++ - 模板类模板成员函数(member function template)隐式处理(implicit)变化
模板类模板成员函数(member function template)隐式处理(implicit)变化 本文地址: http://blog.csdn.net/caroline_wendy/articl ...
- C++模板编程中只特化模板类的一个成员函数
模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数.类模板中大多数成员函数的功能可能是一模一样的,特化时我们可能只需要重新实现1.2个成员函数即可.在这种情况下,如果全 ...
- C++模板编程中只特化模板类的一个成员函数(花样特化一个成员函数)
转自:https://www.cnblogs.com/zhoug2020/p/6581477.html 模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数.类模板中大多 ...
随机推荐
- 浅谈SDN和NFV之间的关系
一个行业固定设备的折旧周期很长,任何变革的发生都绝非易事,但是网络却一次性面临两项革新--软件定义网络(SDN)和网络功能虚拟化(NFV),在变革网络的过程中,二者若想取得成功可能会依赖彼此的技术,或 ...
- js 常见混乱
slice(begin.end) 复制出一个新的数组或是一个新的字符串,其中end 不包括end本身 splice(begin,howmany,item1....itemn) 更改原先的array 会 ...
- 移动web前端小结(一)--摘自小鹿_同学
一.框架 框架:Bootstrap+HTML5 Boilerplate. 两个框架整合到一起可以看一下这位大神的文章:<使用 Bootstrap 和 HTML5 Boilerplate 开始一个 ...
- STM32之独立看门狗与窗口看门狗总结
一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...
- Java 第8章 循环结构进阶
循环结构进阶 什么是二重循环? 二重循环的执行顺序是什么?
- Android 时间维护服务 TimeService(针对于特殊定制设备)
此方法针对于无法自动获取网络时间的特殊设备,正常 Android 设备直接调用 System.currentTimeMillis(); 方法获取当前时间即可. TimeService 集成于 Serv ...
- 阿里云RDS for MySQL备份文件+binlog恢复过程中碰到的一些问题
1.一开始通过官方下载有的压缩包安装,碰到各种依赖问题,最后采用YUM安装 1.通过yum安装percona-Xtrabackup 1.1 先安装依赖: yum install perl-DBI yu ...
- C#中SQL Server数据库连接池使用及连接字符串部分关键字使用说明
(1) 数据库的连接使用后,必须采用close()连接等效的方法关闭连接.只有关闭后,连接才能进入连接池. 参见微软的使用连接池说明:https://msdn.microsoft.com/zh-cn/ ...
- 解决Ubuntu下Chrome浏览器网页中文字体混乱
在Ubuntu下使用Chrome浏览器时碰到了网页中文字体混乱的现象: 黑体和楷体混杂,看起来非常不美观. 这是由于许多网页并没有指定字体,然后浏览器将调用系统默认字体配置. 首先,安装文泉驿字体: ...
- java-注解
概念 Annontation是Java5开始引入的新特征.中文名称一般叫注解.它提供了一种安全的类似注释的机制,用来将任何的信息或元数据与程序元素(类.方法.成员变量等)进行关联.更通俗的意思是为程序 ...