1. 程式人生 > >C++中的萃取機制(traits)

C++中的萃取機制(traits)

由來

在設計迭代器(iterator)時,考慮到需要經常訪問迭代器所指物件之型別,稱之為該迭代器的value_type,利用內嵌型別宣告typedef可輕鬆實現隱藏所指物件型別:

template<typename T>
struct Iterator
{
    typedef T value_type;
}

如此一來,泛型演算法便可通過typename Iterator&lt;T&gt;::value_type獲取value_type

template<typename Iterator>
typename Iterator::value_type getValue(Iterator iter)
{
    return
*iter; }

在客戶端,我們可做如下形式的呼叫:

vector<int> ivec{0, 1, 2, 3};
int val = getValue(ivec.begin());

STL要求,支援迭代器的演算法,也應該支援原生指標,比如:

int arr[] = {0, 1, 2};
int val = getValue(arr+1);
                # 此時編譯器會報錯

因為int*型別(也即原生指標)不能內嵌型別宣告,這裡需要多一層的封裝,萃取編譯技術應運而生。進一步封裝,便可進一步特化。

template<typename Iterator>
struct
iterator_traits { typedef typename Iterator::value_type value_type; }; // 特化版本一,針對原生指標型別 template<typename T> struct iterator_triats<T*> { typedef T value_type; }; // 特化版本二, template<typename T> struct iterator_traits<const T*> { typedef T value_type; }; // 重寫getValue()方法
template<typename Iterator> typename iterator_traits<Iterator>::value_type getValue(Iterator iter) { return *iter; }

這時便可實現對原生指標型別的支援:

int val = getValue(arr+1);

型別萃取(type traits)

struct __true_type{};
struct __false_type{};
template<typename T>
struct __type_traits
{
    typedef __false_type has_trivial_default_constructor;
    typedef __false_type has_trivial_destructor;
};

template<>
struct __type_traits<int>
{
    typedef __true_type has_trivial_default_constructor;
    typedef __true_type has_trivial_destructor;
};

References