問題:如何偵知任意型別 t 是否可以自動轉換為型別 u?
方案:偵測轉換能力的想法:合併運用 sizeof 和過載函式。
1 依賴 sizeof,sizeof 有著驚人的能力,你可以把 sizeof 用在任何表示式身上,不論後者有多複雜。sizeof 會直接傳回大小,不需拖到執行期才評估。這意味著 sizeof 可以感知過載 (overloading)、模板具現(template instantiation)、轉換規則(conversion rules)、或任何可發生於c++ 表示式身上的機制。
sizeof 的其他用法可參考:
2 提供兩個過載函式:其中乙個接受 u(u 型別代表目前討論中的轉換目標)。另乙個接受 」任何其他型別「。以型別 t 的暫時物件來呼叫過載函式,t 是否可轉換成 u 正式我們要驗證的。如果接受 u的那個函式被呼叫,我們就知道 t 可轉換為 u;否則 t便無法轉換為 u。為了知道哪乙個函式被呼叫,兩個過載函式的返回不同的返回型別,並以 sizeof 來區分其大小。型別本身無關緊要,重要的是其大小必須不同。
[cpp] view plain copy
01.// 最簡單區分返回值大小的方法
02.typedef char small;
03.class big ;
04.// 宣告兩個過載函式
05.small test(u);
06.big test(...); // 呼叫乙個帶省略符的函式,可接受任何型別的引數,編譯器優先選擇最準確的過載函式,所以這當然是最差的選擇
07.
08.// 這裡呼叫 t() 的預設建構函式
09.const bool convexists = sizeof (test(t())) == sizeof(small); // sizeof 會在編譯器求得函式返回值的大小,但不會執行該函式體
10.// 如果 t 型別的預設構造為 private,可以構造乙個 t maket();
11.const bool convexists = sizeof (test(maket())) == sizeof(small);
當然,我們可以用 class template 包裝,隱藏 型別推到的細節:
[cpp] view plain copy
01.template
02.class conversion
03.;
06. static small test(u); // 很顯然這裡只能定義靜態成員函式,否則下面 enum中 existes表示式中 sizeof 只能評估呼叫靜態的成員函式,而普通的成員函式的呼叫依賴於類的例項物件。
07. static big test(...);
08. static t maket();
09.public:
10. // exists 值為 true 時,t 可轉換為型別 u
11. enum ;
12. // exist2way 表示 t 和 u 之間是否可以雙向轉換。例如 int和 double 可以雙向轉換
13. enum ;
14. // 如果 t 和 u 是相同的型別, 這個值便為true
15. enum ;
16.};
17.可以通過偏特化來實現sametype
18.template
19.class conversion < t, t >
20.;
23.};
有了 conversion 的幫助,可以定義巨集來簡化判斷繼承關係:
[cpp] view plain copy
01.#define supersubclass(t, u) \
02. (conversion::exists && \
03. !conversion::sametype)
如果 u 是public 繼承於 t,或 t 或 u 是同一型別,那麼 supersubclass(t, u) 會傳回 true。
當 supersubclass(t, u) 對 const u* 和 const t* 作「可轉換」評估時,只有三種情況下 const u* 可以隱式轉換為 const t*:
1 t 和 u是同一種型別
2 t 是 u 的乙個 unambiguous (不模稜兩可的、非歧義的) public base。
3 t 是 void。
第三種情況可以再第二次測試中解決掉。更嚴謹的測試:
[cpp] view plain copy
01.#define supersubclass_strict(t, u) \
02. (supersubclass(t, u) && \
03. !conversion::sametype)
為何這些**都加上 const 修飾?原因是我們不希望因 const 而導致轉型失敗。 如果 template **實施 const 兩次(對乙個已經是 const 的型別而言),第二個 const 會被忽略。在 supersubclass 中使用 const,更安全些。
supersubclass 很明顯告訴使用者 判斷 t 是否是 u 的父類。
測試:[cpp] view plain copy
01.class super{};
02.class sub :public super {};
03.int main()
04.{
05. cout << conversion::exists << ' '
06. << conversion::exists << ' '
07. << conversion>::exists << endl;
08. bool bflag = supersubclass(super, sub);
09. bflag = supersubclass_strict(super, sub);
10.
11.return 0;
過載模板函式
include using namespace std 求兩個int值的最大值 inline int const max int const a,int const b 求兩個任意型別值中的最大者 template inline t const max t const a,t const b int...
C 模板過載
產生背景 需要多個對不同型別使用同一種演算法函式時可以使用模板,但是並非所有的型別都使用同一種演算法,為了解決這個問題,產生了模板過載。tips 1.如同函式的過載一樣,模板過載函式的特徵標必須不同 2.並非所有的模板引數都必須是模板引數型別 顯示具體化 explicit specializatio...
模板和過載
1.過載函式,其實也很好理解。什麼是過載函式呢?就是共用同一函式名。在共用中得注意的事項 1 函式名相同但是函式的形參型別名不同或者是形參的個數不同。2 在宣告形參的時候,如果在函式中,宣告了乙個形參是const限定的,在實參中,應該說是對應的,其實const 限定的可以傳遞給const限定的形參,...