-
让gcc支撑成员函数模板的trick
添加时间:2013-7-12 点击量:让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>)了。