函数模板的trick
函数模板的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: <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>)了。
函数模板的trick的更多相关文章
- 让gcc支持成员函数模板的trick
让gcc支持成员函数模板的trick 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循“署名-非商业用途-保持一致”创作公用协议 gcc 4.7.3 不支持成员 ...
- c++函数模板作为类的成员函数,编译报错LNK2019的解决方法
为了使某个类的成员函数能对不同的参数进行相同的处理,需要用到函数模板,即template<typename T> void Function(). 编译时报错LNK2019 解决方法: 1 ...
- C++STL - 函数模板
模板主要是为了泛型编程,做到与类型无关 模板有函数模板和类模板,本文主要整理的是函数模板 1.函数模板定义 template<typename 类型形参1,typename 类型形参2,...& ...
- 使用getopt_long来解析参数的小函数模板
getopt_long原型 #define no_argument 0 #define required_argument 1 #define optional_argument 2 struct o ...
- C++函数重载和函数模板
1.函数重载 这是小菜鸟写的一个例子. 函数重载应该注意以下几点: 1.1重载函数有类似的功能: 1.2只能以参数的类型(形参个数和类型)来重载函数, int max(int a,int b);flo ...
- 零值初始化&字符串常数作为函数模板参数
1.在定义一个局部变量时,并希望该局部变量的初始化一个值,可以显示调用其默认构造函数,使其值为0(bool类型默认值为false). template <typename T> void ...
- 不可或缺 Windows Native (16) - C++: 函数重载, 缺省参数, 内联函数, 函数模板
[源码下载] 不可或缺 Windows Native (16) - C++: 函数重载, 缺省参数, 内联函数, 函数模板 作者:webabcd 介绍不可或缺 Windows Native 之 C++ ...
- Effective C++ -----条款45:运用成员函数模板接受所有兼容类型
请使用member function templates(成员函数模板)生成”可接受所有兼容类型“的函数. 如果你声明member templates 用于“泛化copy构造”或“泛化assignme ...
- c++ 左值右值 函数模板
1.先看一段代码,这就是一种函数模板的用法,但是红色的部分如果把a写成a++或者写成一个常量比如1,都是编译不过的,因为如果是a++的话,实际上首先是取得a的 值0,而0作为一个常量没有地址.写成1也 ...
随机推荐
- 我在Github上的flare-spark项目
Flare-Spark 介绍 我在自己的github上建了个flare-spark项目,本身是Apache Spark项目Master分支的镜像.在Spark的基础上,添加了flare子项目. 估计大 ...
- AlphaBlend參数BLENDFUNCTION
AlphaBlend是Window自带的GDI函数,在作GUI的时候为了达到更美丽的效果我们经常常使用它. BLENDFUNCTION是AlphaBlend用控制透明效果的重要參数. 定义例如以下: ...
- c语言中实现从0-1的随机数输出
原文:c语言中实现从0-1的随机数输出 今天晚上同学问了一个巨简单的问题,问我怎么用c语言输出0-1的随机数,可别说,一时之间还想不出来.在写的过程中发现,直接调用random函数还不能实现,用以下方 ...
- C语言库函数大全及应用实例一
原文:C语言库函数大全及应用实例一 [编程资料]C语言库函数大全及应用实例一 函数名: abort 功 能: 异常终止一个进程 用 法: ...
- Android接口测试-JUnit入门
1.下载:http://www.junit.org 2.配置AndroidManifest.xml,在application节点加入 <!--使用单元测试库--> <u ...
- 《Shell十三问》笔记(上)
<shell十三问>是网中人前辈首发在CU论坛上对SHELL的一些整理,非常值得一读 注:笔记的标号非问题标号,而是知识点的标号.本篇笔记记录的是1-10问的知识点 (1)IFS:Shel ...
- openwrt路由器更换了Flash之后需要修改的源码
假如我使用的是WR703N,改为8M内存: 1 修改openwrt/target/linux/ar71xx/image/Makefile文件 $(eval $(call SingleProfile,T ...
- SQLCMD的介绍
原文:SQLCMD的介绍 sqlcmd -S SERVERNAME -U USERNAME -P PASSWORD -i filename.sql 下面的内容是详细介绍sqlcmd的,有兴趣的朋友可以 ...
- 读书笔记—CLR via C#章节11-13
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 【转】Android学习之AndroidManifest.xml清单之<uses-feature>
无意之中看了几个小时的官方英文文档,关于<uses-feature>的介绍.有必要在这里记录一下,应该有很多人不知道<uses-feature>到底是做什么用的,因为我们平时根 ...