C++ template学习笔记
本专栏是《C++ template》这本书的学习笔记
班公湖里洗过脚
上马击狂胡,下马草军书
展开
-
C++ template模板术语(第7章)
本章介绍模板的术语,关于模板,我说通常理解的是“类模板”还是“模板类”呢?这两个含义是有区别的,在C++中,类和联合(union)都被称为类类型(class type)。如果不加额外的限定,我们通常所说的"类(class)"是指:用关键字class或者struct引入的类类型(class type)。需要特别注意的一点就是:类类型(class type)包括联合(union),而“类(class)”不包括联合(union)。原创 2020-10-26 19:02:39 · 122 阅读 · 0 评论 -
C++ template调试模板(6.6节)
当需要调试模板的时候,我们将会面临来自两方面的挑战。一种挑战来自模板的编写者:针对某一个模板, 如果它的任何一个模板实参都已符合文档所编写的要求,那么我们如何才能够保证模板可以正确地运作呢? 另一种挑战正好来自对方的一方(即模板的使用者):在遇到模板的行为和文档中所描述的情况有差异的时候, 模板的用户如何才能发现哪个模板参数违反了文档要求,或者是违反了模板参数的哪条要求呢? 在深入讨论这些话题之前,让我们先来考察可以强加给模板参数的一些约束,这是非常有必要的。因为在...原创 2020-08-01 08:07:22 · 1537 阅读 · 0 评论 -
C++ template模板和内联(6.4节, 6.5节)
模板和内联 把短小函数声明为内联函数是提高运行效率所普遍采用的方法。inline修饰表明的是一种实现:在函数的调用处使用函数体(即内容)直接进行内联替换,它的效率要优于普通函数的调用机制(针对短小函数而)。然而,标准并没有强制编译器实现这种”在调用处执行内联替换“的机制,实际上,编译器也会根据调用的上下文来决定是否时行替换。 函数模板和内联函数都可以被定义于多个翻译单元中。通常,我们是通过下面途径来获取这个实现:把定义放在一个头文件中,而这个头文件被多个dot-C文件所包含(#in...原创 2020-07-19 16:00:56 · 1876 阅读 · 0 评论 -
C++template 显示实例化(6.2节, 6.3节)
显示实例化 包含模型能够确保所有需要的模板都已经实例化。这是因为:当需要进行实例化的时候,C++编译系统会自动产生对应的实例化体。另外,C++标准还提供了一种手工实例化模板的机制:显示实例化指示符(explicit instantiation directive)。 1 显示实例化的例子 为了说明手工实例化,让我们回顾前面那个导致链接器错误的例子。在此,为了避免这个链接其错误,我们可以通过给程序添加下面的文件: myfirstinst.cpp #include "m...原创 2020-07-19 16:00:34 · 711 阅读 · 0 评论 -
C++template 包含模型(6.1节)
我们可以用几种方法来组织模板源代码。这一节将给出最常用的方法:包含模型(inclusion model)。1.链接器错误 类(class)和其他类型(other type)都被放在一个头文件中。通常而方,头文件是一个扩展名为.hpp(或者.H, .h, .hh, .hxx)的文件。 对于全局变量和(非内联)函数,只有声明放在头文件中,定义则位于dot-C文件。通常而言,dot-C文件是指扩展名为.cpp(或者.C,.c, .cc, .cxx)的文件。...原创 2020-07-19 16:00:02 · 240 阅读 · 0 评论 -
C++ template使用字符串作为函数模板的实参(5.6节)
有时,把字符串传递给函数模板的引用参数会导致出人意料的运行结果。考虑下面的程序:#include <iostream>#include <string>template <typename T>inline T const& max(T const &a, T const &b){ return a < b ? b : a;}int main(){ std::string s; std::s.原创 2020-07-13 23:42:10 · 2981 阅读 · 0 评论 -
C++template 零初始化(5.5节)
对于int, double或者指针等基本类型,并不存在“用一个有用的缺省值来对它们进行初始化”的缺省构造函数;相反,任何未被初始化的局部变量都具有一个不确定的(undefined)值:void foo(){ int x; //x具有一个不确定的值 int *ptr; //ptr指向某块内存(并非无所指)}现在,假如你在编写模板,并且希望模板类型的变量都已经用缺省值初始化完毕,那么这时你会遇到问题,内建类型并不能满足你的要求:template <typename ...原创 2020-07-13 23:41:17 · 553 阅读 · 0 评论 -
C++ template 模板的模板参数(5.4节)
有时,让模板参数本身成为模板是很有用的,我们将继续以stack类模板作为例子,来说明模板的模板参数的用途。在Stack的例子中,如果要使用一个和缺省值不同的内部容器,程序员必须两次指定元素类型。也就是说,为了指定内部容器的类型,你需要同时传递容器的类型和它所含元素的类型。如下:Stack<int, std::vector<int>> vStack; //使用vector的int栈然而,借助于模板的模板参数,你可以只指定容器的类型而不需要指定所含元素的类型,就可以声明这个Stack原创 2020-07-13 23:40:30 · 995 阅读 · 0 评论 -
C++ template成员模板(5.3节)
类成员也可以是模板,嵌套类和成员函数都可以作为模板。我们可以通过一个Stack<>类模板来说明这种(作为模板的)能力的优点和应用方法。通常而言,栈之间只有在类型完全相同时才能互相赋值,其中类型指的是元素的类型。就是说,对于元素类型不同的栈,你不能对它们进行相互赋值 ,即使这两种(元素的)类型之间存隐式类型转换。譬如:Stack<int> intStack1, intStack2; //int栈Stack<float> floatStack; //float栈....原创 2020-07-13 23:39:31 · 526 阅读 · 0 评论 -
C++ template 关键字typename(5.1节, 5.2节)
本章给出模板的一些更深入的基础知识,它们都是和模板的实际应用密切相关的,包括关键字typename的另一种用法,把成员函数和嵌套类也定义成模板,模板的模板参数(template template parameters),零初始化和使用字符串作为模板实参时所要注意的一些细节,虽然这些技术具有很强的技巧性,但每个C++程序员日常都应对它略有耳闻。关键字typename在C++标准化过程中,引入关键字typename是为了说明:模板内部的标识符可以是一个类型,譬如下面的例子:template &...原创 2020-07-07 20:13:47 · 527 阅读 · 0 评论 -
C++ teleplate非类型的函数模板参数(4.2节,4.3节)
//addval.h#ifndef ADDVAL_H#define ADDVAL_H#include <iostream>template<typename T, int VAL>T addValue(T const &x){ std::cout << "x====" << x << " VAL===" << VAL << std::endl; return x + VAL;}...原创 2020-07-07 20:07:42 · 221 阅读 · 0 评论 -
C++ Template非类型的类模板参数(4.1节)
对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数。在基于类型参数的模板中,定义一些具体细节未加确定的代码,直到代码被调用时这些细节才被真正确定。然而,在这里,我们面对的这些细节是值(value),而不是类型。当要使用基于值的模板时,你必须显式地指定这些值,才能够对模板进行实例化,并获得最终代码。 较之前的Stack例子的实现,可以使用元素数目固定的数组来实现Stack。这个方法(用固定大小的数组)的优点是:无论是由你来亲自管理内存,还是由标准容器来管理内存都可以避免内...原创 2020-07-07 20:07:16 · 663 阅读 · 0 评论 -
C++ Template缺省模板实参(3.5节)
对于类模板,可以为模板参数定义缺省值:这些值就被称为缺省模板实参:而且它们还可以引用之前的模板参数。例侞,在类Stack<>中,你可以把用于管理元素的容器定义为第2个模板参数,并且使用std::vector<>作为它的缺省值://stack3.h#ifndef STACK3_H#define STACK3_H#include <vector>#include <stdexcept>template <typename T, typen原创 2020-07-06 15:28:31 · 1075 阅读 · 0 评论 -
C++ Template类模板的特化(3.3节, 3.4节)
用模板实参来特化类模板,和函数模板的重载类似,通过特化类模块,可以优化基于某种特定类型的实现,或者克服某种特定类型在实例化类模板时所出现的不足。另外,如果要特一个类模板,你还要特化该类模板的所有成员函数。虽然也可以只特化某个成员,但这个做法并没有特化整个类,也就没有特化整个类模板。为了特化一个类模板,你必须在起始处声明一个template<>,接下来声明用来特化类模板的类型。这个类型被用作模板实参,且必须在类名的后面直接指定:template <>class Stack原创 2020-07-06 14:20:13 · 754 阅读 · 0 评论 -
C++ Template类模板(3.1节,3.2节)
与函数相似,类也可以被一种或多种类型参数化。容器类就是一个具有这种特性的典型例子,它通常被用于管理某种特定类型的元素。只要使用类模板,你就可以实现容器类,而不需要确定容器中元素的类型。1.类模板的定义template <typename T>class Stack{....};2.类模板的使用示例//stack1.h#ifndef STACK1_H_#define STACK1_H_#include <vector>#include <s原创 2020-06-14 11:58:02 · 191 阅读 · 0 评论 -
C++ Template重载函数模板(2.4节)
和普通函数一样,函灵敏模板也可以被重载。就是说,相同的函数名称可以具有不同的函数定义:于是,当使用函数名称进行函函数调用的时候,C++编译器必须决定究竟要调用哪个候选 函数。//重载函数模板#include <iostream>#include <string>//求两个int值的最大值inline int const& max(int const &a, int const& b){ std::cout << "a=...原创 2020-05-30 12:15:18 · 1627 阅读 · 0 评论 -
C++ Template函数模板参数(2.3节)
在前面的示例中,我们使用的函数模板的实参都是一样的,但其实函数模板的参数也可以不一样,并且可以是多个,这样就可以定制化一些特殊用途的函数模板,例如://函数模板的参数#include <iostream>#include <string>template <typename T1, typename T2>inline T1 max2(T1 const& a, T2 const& b) //这是返回参数一定要用T1,不能是T1 co原创 2020-05-30 10:29:06 · 784 阅读 · 0 评论 -
C++ Template初识函数模板(2.1节,2.2节)
C++模板是泛型编程基础,泛型编程即以一种独立于任何特定类型的方式编写代码。为什么要使用模板,有哪些好处呢,首先来看下面一个示例 #include <iostream>using namespace std;int max(int a, int b){ return a > b ? a : b;}float max(float a, float b){ return a > b ? a : b;}double max(doubl...原创 2020-05-27 14:44:53 · 247 阅读 · 0 评论