函数模板的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....\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: <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>....\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>)了。

 
 
 
分类: C/C++
标签: C++gcctemplate

最新文章

  1. ubuntu /var/log/下文件介绍
  2. CF448C Painting Fence (分治递归)
  3. Jquery如何判断Radiobutton是否选中
  4. 不引用office动态库导出excel
  5. (六)STM32的时钟系统
  6. Node.js 学习(四)Node.js 回调函数
  7. 武汉科技大学ACM :1001: A + B Problem
  8. Java中的工具类和新特性
  9. 2.Math对象
  10. 【蒙地卡罗法求PI】
  11. 学习java线程学习笔记
  12. Red Hat Enterprise Linux7的安装与oracle 12c的安装
  13. Redis linux 外部telnet访问不通
  14. SHELL脚本--expr命令全解
  15. 2018-软工机试-C-和你在一起
  16. sklearn训练感知器用iris数据集
  17. Java之反射举例
  18. C#中巧用#if DEBUG 进行调试
  19. webGL 光照
  20. Spring核心思想:“控制反转”,也叫“依赖注入” 的理解

热门文章

  1. perconaXTRADB Cluster在Redhat Linux上的安装
  2. .NET源代码的内部排序实现
  3. python向mysql中存储JSON及Nodejs取出
  4. 百度地图 api 功能封装类 (ZMap.js) 本地搜索,范围查找实例
  5. C#6.0 中的那些新特性
  6. POJ3187 Backward Digit Sums
  7. CRT
  8. AjaxPro使用说明文档
  9. Mysql高级之索引
  10. C# 语言的多线程编程,完全是本科OS里的知识