C++Primer学习:模板特例化

(1)类模板特例化

某些时候通用模板的定义不适用,这个时候就需要对特定类型的实例进行特例化.

例子1:hash类模板是标准库里的一个模板,我们现在需要对它进行特例化,定义hash<Sales_data>,使得关联容器可以存储相应的对象.

//注意,需要在sales_data上声明友元.
#include "unordered_set"
#include "Sales.h"
namespace std{//打开名字空间

    template<>//定义一个特例化的hash类
    struct hash<Sales_data>
    {
        typedef size_t result_type;
        typedef Sales_data argument_type;
        size_t operator() (const Sales_data&) const;
    };
    size_t hash<Sales_data>:: operator()(const Sales_data& s) const
    {
        return hash<string>()(s.bookNo) ^ hash<unsigned>()(s.units_sold)
            ^ hash<double>()(s.revenue);//注意,hash<string>()生成一个不具名的对象,该对象调用()
    }
}
int main(int argc, char** argv)
{

    unordered_multiset<Sales_data> 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)<<endl;
    return 0;
}

(2)函数模板特例化:和类模板特例化相似,我有时候需要将函数模板特例化。下面通过一个例子来进行分析.

例子2:定义一个函数模板,统计一个给定值在vector中出现的次数。并且为该模板编写特例化版本来处理vector<const char *>

template<typename T>
size_t compute(const vector<T>& 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;
}

你可能感兴趣的:(C++Primer学习:模板特例化)