让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: 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的更多相关文章

  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. Android安全之Https中间人攻击漏洞

    Android安全之Https中间人攻击漏洞 0X01 概述   HTTPS,是一种网络安全传输协议,利用SSL/TLS来对数据包进行加密,以提供对网络服务器的身份认证,保护交换数据的隐私与完整性. ...

  2. java执行效率低,但效率就低吗?

    很多没用过java或者没怎么用过java的程序员都会说java执行效率低,这种言论时不时的在影响着我这个初级的java开发者. java执行效率低因如下几点导致(和C++比较): 1,java不允许内 ...

  3. SVN强制解锁操作

    如果是其他人锁定文件,而你期望对此文件操作,可进行偷锁操作: 1,将被锁定文件SVN Check out-到本机硬盘. 2,点击文件右键,选择get lock 3,勾上steal the locks ...

  4. C++builder中使用TScrollBox 以后,让scrollBox相应鼠标的上下滑动

    1.在窗口的事件里搜索 mouseWheel的方法 2.在.cpp文件里实现下面的代码 void __fastcall TForm1::mouseWheel(TObject *Sender, TShi ...

  5. 关于display: box 和 box-flex

    这两天做手机项目,使用到这个css3新属性.现在还不为所有浏览器支持,所以使用的时候要加上前缀.使用方法见下面: html代码: <div class="s-indLine" ...

  6. spark单机环境下运行一些解决问题

    ERROR1.hadoop依赖 [ERROR] - Failed to locate the winutils binary in the hadoop binary path   java.io.I ...

  7. [UCSD白板题] Number of Inversions

    Problem Introduction An inversion of a sequence \(a_0,a_1,\cdots,a_{n-1}\) is a pair of indices \(0 ...

  8. ILSpy搜索功能加强版

    1.修改搜索功能,增加如下的额外搜索选项 A.按文本搜索(默认选项) B.按通配符搜索 C.按正则表达式搜索 2.搜索增加如下特性: A.可以按照名字空间检索特定名字空间下的所有类. B.修正了官方版 ...

  9. BZOJ2888 资源运输(LCT启发式合并)

    这道题目太神啦! 我们考虑他的每一次合并操作,为了维护两棵树合并后树的重心,我们只好一个一个的把节点加进去.那么这样一来看上去似乎就是一次操作O(nlogn),但是我们拥有数据结构的合并利器--启发式 ...

  10. Android中将布局文件转成bitmap

    在实践中发现,有些需要打印的小票高度小于屏幕的高度,而有些小票内容过多高度高于屏幕高度. 小于屏幕高度的布局文件转成bitmap较为容易,高于屏幕高度的布局文件转成长图bitmap较为复杂. 一.小于 ...