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