C++ 編譯期怎麼判斷一個類是不是純虛類,我有一段代碼,可以達到效果,但不知道為什麼這麼寫?
定義:
template &
struct IsAbstract
{
typedef char SmallType;
typedef int LargeType;template &
static char Test(U(*)[1]);
template &
static int Test(...);const static bool Result = sizeof(Test&
(NULL)) == sizeof(LargeType);
};
使用:
IsAbstract&::Result 就是T類是不是純虛類的bool值.補充: 我大概知道它是利用了 純虛類 和 普通類 的成員函數指針大小不同來判斷的,但為什麼這樣寫可以判斷,原理是什麼,那兩 Test 函數又為什麼寫成那樣呢?
請大神賜教。
這是利用了Substitution failure is not an error原則,有重載的函數匹配模板參數時如果不成功並不算編譯錯誤,會繼續嘗試對其它的重載進行匹配。這個trait的邏輯很簡單,判斷Test&
template &
static char Test(U(*)[1]);
不能匹配成功。因為這裡的參數是指向U數組的指針,數組要求類型不能是reference(引用), void(空), function(函數)和abstract(抽象)。此處失敗後
template &
static int Test(...);
可以匹配成功,因為...匹配任意參數。
所以T是抽象類時Test&template &
static char Test(U u[1]);
為了調用這個函數你需要創建一個對象,但是對於抽象類在編譯期間會失敗。
然後考慮指針template &
static char Test(U* u);
這種寫法的好處是我們不用創建對象,可以使用空指針作為參數。但抽象類的指針是合法的,所以不管是什麼類型都能匹配成功。
那麼把兩種寫法結合起來就是題中的寫法,既使用了數組類型限定了可以匹配的類型,又可以使用空指針去匹配。sfinae 。
http://en.cppreference.com/w/cpp/language/sfinae
參見其中 type sfinae 部分。參見pongba的type_traits說明boost源碼剖析之:泛型編程精靈type_traits(rev#2)
推薦閱讀:
※操作系統有什麼自相矛盾的地方?
※Linux 下的伺服器時間同步方案有哪些?
※Linux, emacs難以割捨的情結,單位使用的是win + vs,怎麼辦?
※Linux下C/C++動態庫在運行時是怎樣載入進來的?
※為什麼 Linux 沒有註冊表?為什麼說註冊表是萬惡之源?