type traits 之 本質論

2021-07-01 23:32:49 字數 2320 閱讀 7691

侯捷老師在《stl 原始碼剖析》說:traits程式設計方法是一把開啟stl源**大門的鑰匙,其重要性也就不必再說了。既然traits程式設計方法如此重要,那麼掌握並領悟其精髓是相當必要了。

trait的意思是什麼?英文意思是attribute,feature等等,中文意思可以解釋為特點, 特性。那麼type trait就是型別的特性。那什麼是型別?型別的特性又有哪些呢?型別也即是使用者自定義的型別或是語言提供的一些基本型別。每個型別都具有相關的特性,這些特性可能包括:是否有相應的構造方法和析構方法、這一型別引申出來相應的指標型別和引用型別(比如iterator_traits中的成員)等等。其實乙個型別所具有的特性是多得數也數不清的,只能從實踐(程式設計)的需要去看這個型別具有什麼樣的特性。如stl中的destroy需根據型別是否具備有關痛癢的析構方法來決定具體操作。是否具備有關痛癢的析構方法就是型別的乙個特性,在程式設計實踐中的特性。自定義的型別可能就具備有關痛癢的析構方法,而語言提供的一些基本型別就沒有。

traits技巧對型別做了什麼?有什麼作用?型別和型別的特性本是耦合在一起,通過traits技巧就可以將兩者解耦。從某種意思上說traits方法也是對型別的特性做了泛化的工作,通過traits提供的型別特性是泛化的型別特性。從演算法使用traits角度看,使用某一泛型型別的演算法不必關注具體的型別特性(關注的是泛化的型別特性,即通過traits提供的型別特性)就可以做出正確的演算法過程操作;從可擴充套件角度看,增加或修改新的型別不影響其它的**,但如果是在type_traits類中增加或修改型別特性對其它**有極大的影響;從效率方法看,使用type_traits的演算法多型性選擇是在編譯時決定的,比起在執行時決定效率更好。

在實際**中所有的具體的型別特性沒有基類,但概念上是存在的。如果我們再把通過引數多型性的演算法也看成有基類情況的假想,就有下圖所示的關係:

從圖中可看出演算法destroy不必關心具體的型別特性traits,client不用關心具體的destroy。destroy概念上存在的基類是通過引數多型實現的,traits概念上存在的基類是通過type_traits程式設計方法實現的。

另外得注意的是stl中的iterator相關type_traits的使用跟這裡所說的有點不同,如果把型別特性從類中剝離出來看待,那就完全相同了。如何剝離,分析**時遇到type_traits相關的含有型別特性的類只看成是型別特性,跟型別特性無關的全都忽略掉。

// my_type_traits.h開始

#ifndef my_type_traits_h

#define my_type_traits_h

struct my_true_type ;

struct my_false_type ;

template

struct my_type_traits ;

template<> struct my_type_traits ;

#endif

// my_type_traits.h結束

// my_destruct.h開始

#ifndef my_destruct_h

#define my_destruct_h

#include

#include "my_type_traits.h"

using std::cout;

using std::endl;

template

inline void myconstruct(t1 *p, const t2& value)

template

inline void mydestroy(t *p)

template

inline void _mydestroy(t *p, my_true_type)

template

inline void _mydestroy(t *p, my_false_type)

#endif

// my_destruct.h結束

// test_type_traits.cpp開始

#include

#include "my_destruct.h"

using std::cout;

using std::endl;

class testclass

testclass(const testclass& test_class)

~testclass()

private:

int *data;

};

int main(void)

}// test_type_traits.cpp結束

繼承本質論

1.引言 關於繼承,你是否駕熟就輕,關於繼承,你是否瞭如指掌。本文不討論繼承的基本概念,我們回歸本質,從編譯器執行的角度來揭示.net繼承中的執行本源,來發現子類物件是如何實現了對父類成員與方法的繼承,以最為簡陋的示例來揭示繼承的實質,闡述繼承機制是如何被執行的,這對於更好的理解繼承,是必要且必然的...

繼承本質論

原創作品,轉貼請註明作者和出處。關於繼承,你是否駕熟就輕,關於繼承,你是否瞭如指掌。本文不討論繼承的基本概念,我們回歸本質,從編譯器執行的角度來揭示.net繼承中的執行本源,來發現子類物件是如何實現了對父類成員與方法的繼承,以最為簡陋的示例來揭示繼承的實質,闡述繼承機制是如何被執行的,這對於更好的理...

指標本質論

指標本質論 1.指標是什麼?和一般變數有什麼區別?指標就是位址,和一般變數沒有本質區別,僅僅是它有自己的規則。int a 100 int p a printf d n a 100 printf p n p 0xbfa47858 a是乙個變數名,型別是int,值是100,a有自己的位址 a p是乙個變...