注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

SFINAE原理及其在模板中的使用之一原理的简要说明  

2014-07-04 11:38:15|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

SFINAE原理及其在模板中的使用之一原理的简要说明

C++编程中有很多Trick,也就是编程技巧,SFINAE(Substitution failure is not an error),翻译成中文可理解为“匹配失败并不是一个错误”,也就是说这种方法主要就是利用了编译器匹配失败的一种技巧。他的优势也就出现了,他既可以真正的保护模板,提高模板的重载能力,并且进一步可以使得编译时类型推导成为一种可能。

#include <cstdio> 

 

template<typename C> char check(int C::*); 

template<typename T> float check(...); 

 

template<typename T> 

bool IsClassType() { 

    return sizeof(check<T>(0))==1 ; 

}; 

 

class One;   

int main() 

    printf("Is A Class Type %d\n",IsClassType<std::size_t>()); 

    printf("Is A Class Type %d\n",IsClassType<One>()); 

    return 0; 

}

看上面的代码(其来自:http://www.cnblogs.com/rocketfan/archive/2009/09/18/1568945.html

对于模板template<typename C> char check(int C::*),只有当C类型为类时,才可能有int C::* 这样的类型(表示一个指针,指向C类的某int型成员),这样才能匹配此模板。而对于template<typename T> float check(...),可匹配任意类型的T。所以当check<int>(0)不能匹配前者时,它会匹配后者,从而使IsClassType能得到正确的结果。利用SFINAE原则,可以做很多类型推导:判断一个类型是否为某类型或某类类型(如判断T是否为class类型),类型是否相等(T1T2是否为同一类型),类型选择(根据某类型,选择T1类或T2类),判断两类型是否有继承关系等等。

 

模板的另一重要特性为静态性。这点是指模板的实例化是编译时进行时,程序运行时,已经是模板实例的结果了。利用这一点,可以优化代码。如上面的程序中,计算IsClassType<One>(),实际上已经在编译时计算完毕了,在程序中,直接替代为true;而不是在程序运行进再根据T的类型,重新计算sizeof(check<T>(0))是否等于1。再看一个例子,这程序显示了模板的计算能力(当然,这些计算都是编译时进行了;程序运行时,就能直接输出结果了;具体原理说明见此):

 

#include <iostream>  

 

template<int N>  

class Pow3 {  

  public:  

    enum { result=3*Pow3<N-1>::result };  

};  

 

template<>  

class Pow3<0> {  

  public:  

    enum { result = 1 };  

};  

 

int main()  

{  

    std::cout << "Pow3<7>::result = " << Pow3<7>::result  

              << '\n';  

可见,一些技术和技巧只要用到点子上而不是单纯的为了应用而应用,确实能起到画龙点睛的作用。

C++的水太深了。

  评论这张
 
阅读(394)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017