C++Primer学習:テンプレート特例化

4520 ワード

(1)クラステンプレートの特例化
汎用テンプレートの定義が適用されない場合があり、この場合、特定のタイプのインスタンスを特例化する必要がある.
例1:hashクラステンプレートは標準ライブラリのテンプレートである、hash を定義し、関連コンテナが対応するオブジェクトを格納できるように特例化する必要がある.
//  ,   sales_data     .
#include "unordered_set"
#include "Sales.h"
namespace std{//      

    template<>//        hash 
    struct hash
    {
        typedef size_t result_type;
        typedef Sales_data argument_type;
        size_t operator() (const Sales_data&) const;
    };
    size_t hash:: operator()(const Sales_data& s) const
    {
        return hash<string>()(s.bookNo) ^ hash<unsigned>()(s.units_sold)
            ^ hash<double>()(s.revenue);//  ,hash()          ,     ()
    }
}
int main(int argc, char** argv)
{

    unordered_multiset record;
    Sales_data a("aaa", 10, 2), b("bbbb"), c("ccccc");
    record.insert(a);
    record.insert(b);
    record.insert(c);
    for (auto it : record)
        print(cout, it)<return 0;
}

(2)関数テンプレートの特例化:クラステンプレートの特例化と同様に、関数テンプレートを特例化する必要がある場合があります.以下、一例により分析を行う.
例2:vectorに与えられた値が現れる回数を統計する関数テンプレートを定義します.さらに、vectorを処理するために、テンプレートに特例化されたバージョンを記述する.
template<typename T>
size_t compute(const vector& vec, T key_value)
{
    size_t count = 0;
    for (auto& it : vec)
    {
        if (it == key_value)
            ++count;
    }
    return count;
}
template<>
size_t compute(const vector<const char*>& vec, const char*  key_value)
{
    size_t count = 0;
    for (auto &it : vec)
    if (strcmp(it,key_value)==0)
        ++count;
    return count;
}
//  ,                 const T&,          ,           ,             ,      ,          const char[],      ,            .     T       .

例3:対debug_repは特例化、const char*の文字ポインタを処理する.
template<>
string debug_rep(const char*  p)
{
    std::string ret(p);
    return ret;
}