程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> SFINAE與is_base_of,SFINAEis_base_of

SFINAE與is_base_of,SFINAEis_base_of

編輯:C++入門知識

SFINAE與is_base_of,SFINAEis_base_of


SFINAE:即Substitution Failure Is Not an Error!可以理解為匹配失敗不是錯誤,更嚴格的說應該是參數匹配失敗不是一個編譯時錯誤。

C++函數匹配的順序遵循的原則是按照以下順序

1.尋找參數的完美匹配函數,找到則使用

2.尋找模板函數,若實例化後的函數能夠匹配則使用

3.通過默認類型轉換後的參數去匹配,找到則使用

4.匹配失敗,提示函數匹配錯誤

下面通過實現is_base_of來說明SFINAE的一般用法,來自於

http://stackoverflow.com/questions/2910979/how-does-is-base-of-work

1.定義

 1 namespace blog {
 2     template <class D, class B>
 3     struct ConversionHelper
 4     {
 5         struct Host
 6         {
 7             operator B() const;
 8             operator D();
 9         };
10         typedef char(&yes)[1];
11         typedef char(&no)[2];
12         template <typename T>
13         static yes Test(D, T);
14         static no Test(B, int);
15     };
16 
17     template <class D, class B>
18     struct Conversion
19     {
20         typedef ConversionHelper<D, B> H;
21 
22 typedef typename H::Host Host; 23 enum { exists = sizeof(typename H::yes) == sizeof(H::Test(Host(), int())) }; 24 enum { exists2Way = exists && Conversion<B, DD>::exists }; 25 enum { sameType = false }; 26 }; 27 28 template <class D> 29 struct Conversion<D, D> 30 { 31 enum { exists = 1, exists2Way = 1, sameType = 1 }; 32 }; 33 34 template <class D> 35 struct Conversion<void, D> 36 { 37 enum { exists = 1, exists2Way = 0, sameType = 0 }; 38 }; 39 40 template <class D> 41 struct Conversion<D, void> 42 { 43 enum { exists = 1, exists2Way = 0, sameType = 0 }; 44 }; 45 46 template <> 47 struct Conversion<void, void> 48 { 49 public: 50 enum { exists = 1, exists2Way = 1, sameType = 1 }; 51 }; 52 53 template<typename B, typename D> 54 struct is_base_of { 55 enum { 56 value = (me::Conversion<const D*, const B*>::exists && !me::Conversion<const B*, const void>::sameType) 57 }; 58 }; 59 }

 

1 template<typename B,typename D>
2 struct is_base_of {
3     enum {
4         value = (Conversion<const D*, const B*>::exists && !Conversion<const B*, const void>::sameType)
5     };
6 };

2.使用

1 struct A{};
2 struct B{};
3 struct C : public B
4 {
5     static_assert(blog::is_base_of<C, B>::value, "B is not the base of C");
6     //static_assert(std::is_base_of<C, B>::value, "B is not the base of C");
7 };

  在上面代碼中,由於std::is_base_of<C,B>在struct C結構體中,C還沒有定義完整,因此會出錯。

  而blog::is_base_of<C,B>使用的是指針轉換,當轉換存在時,ConversionHelper::Test(D,T)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved