罗朝辉(飘飘白云)

关注嵌入式操作系统,移动平台,图形开发。-->加微博 ^_^

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  85 随笔 :: 0 文章 :: 169 评论 :: 0 Trackbacks

让gcc支持成员函数模板的trick

罗朝辉 (http://www.cppblog.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>)了。

 
posted on 2013-07-12 22:04 罗朝辉 阅读(6297) 评论(3)  编辑 收藏 引用 所属分类: C/C++

评论

# re: 让gcc支持成员函数模板的trick 2013-07-13 20:54 Marvin
从objective-c转到c++了?  回复  更多评论
  

# re: 让gcc支持成员函数模板的trick 2013-07-14 21:37 罗朝辉
@Marvin
哈哈,本就是从C++起家的~~  回复  更多评论
  

# re: 让gcc支持成员函数模板的trick 2014-08-15 21:28 acmol
其实只需要
a->template b()就可以调用了。。
虽然我也不知道原因。  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理