【Json11源码阅读】06 问题解答,Part_4

template <class T, class = decltype(&T::to_json)>   
Json(const T & t) : Json(t.to_json()) {}  

模板类的定义,要看一下书

PS: 再不更新怕你们说我又玩消失,先更新一篇,书还要继续看,这一章好复杂的说~

模板是泛型编程的基础

  • 函数模板
  • 类模板

假如两个函数只有参数类型不同,如

int compare(const string &v1, const string v2)  
{  
    if( v1 < v2 )  
    {  
        return -1;  
    }  
    
    return 0;  
}  

int compare(const double &v1, const double &v2)  
{  
    if( v1 < v2 )  
    {  
        return -1;  
    }  
    
    return 0;  
}  

可以看出,函数是用来比较大小的。如果我们还想比较两个整数的大小、两个vector的大小等等,是不是还要继续增加函数呢?

可以通过模板将函数的公共部分抽象出来

template <typename T>  
int compare(const T &v1, const T &v2)  
{  
    if( v1 < v2 )  
    {  
        return -1;  
    }  
    
    return 0;   
}  

模板定义以template关键字开始,后跟一个模板参数列表(<typename T>),如果有多个参数,可用逗号分隔

编译器使用实参的类型来推断模板参数T的类型

compare(1, 0);  

T被实例化为int

PS: 也可以使用class关键字代替typename关键字,作用是一样的

非类型模板参数

上面的T指代的是某一个具体的类型,我们还可以对非类型定义模板

template<unsigned N, unsigned M>  
int compare(const char (&pa)[N], const char (&p2)[M])  
{  
    return strcmp(p1, p2);  
}  

只有当我们实例化出模板的一个特定版本时,编译器才会生成代码

为了生成一个实例化版本,编译器需要掌握函数模板的定义。因此,模板的头文件通常既包括声明也包括定义

类模板

对于函数模板,我们看到在实例化时,编译器会自动推断参数的类型。

而类模板不是这样,我们必须在实例化时指明参数的类型,使用尖括号(如vector<int>)

类模板的定义参考P584

如果是在类模板的外部为其定义成员函数,和普通成员函数一样,需要指明函数属于哪个类,即

voic Blob<T>::check(size_type i, const std::string &msg) const  
{  
    
}  

需要注意的是,这里仍要加上模板参数的定义,即

template <typename T>  
voic Blob<T>::check(size_type i, const std::string &msg) const  
{  
    
}  

对于类模板的成员函数,只有当程序用到它时才进行实例化。如果某个成员函数没有被使用,则它不会被实例化。


END


微信公众号:马志峰的编程笔记

记录一名普通程序员的成长之路

posted @ 2017-04-18 07:15  马志峰  阅读(349)  评论(0编辑  收藏  举报