首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

第 16 章 模板与泛型编程

因为编译器需要在编译时实例化模板,此时非类型参数会被一个用户提供编译器推断出值所代替,所以这些值必须是常量表达式。 非类型参数可以是一个整型,对应模板实参必须是常量表达式。...模板中使用到类型相关函数运算符应尽可能少。 为了生成一个实例化版本,编译器需要掌握函数模板模板成员函数定义。...T&); // 绑定到左值和 const右值 某些函数需要将其一个多个实参连同类型不变地转发给其它参数,需要保持转发实参所有性质,包括实参类型是否是 const以及实参是左值还是右值...函数模板可以被另一个模板一个普通函数模板重载,与往常一样,名字相同函数,必须具有不同数量类型参数。...与往常一样,可行函数模板模板)按类型转换(如果对此调用需要的话)来排序。当然,可以用于函数模板调用类型转换是非常有限

1.4K60

第 16 章 模板与泛型编程

因为编译器需要在编译时实例化模板,此时非类型参数会被一个用户提供编译器推断出值所代替,所以这些值必须是常量表达式。 非类型参数可以是一个整型,对应模板实参必须是常量表达式。...模板中使用到类型相关函数运算符应尽可能少。 为了生成一个实例化版本,编译器需要掌握函数模板模板成员函数定义。...T&); // 绑定到左值和 const右值 某些函数需要将其一个多个实参连同类型不变地转发给其它参数,需要保持转发实参所有性质,包括实参类型是否是 const以及实参是左值还是右值...函数模板可以被另一个模板一个普通函数模板重载,与往常一样,名字相同函数,必须具有不同数量类型参数。...与往常一样,可行函数模板模板)按类型转换(如果对此调用需要的话)来排序。当然,可以用于函数模板调用类型转换是非常有限

1.4K20
您找到你想要的搜索结果了吗?
是的
没有找到

C++ 学习笔记

a : b; } 1.5 函数模板重载 1.一个模板函数可以和同名函数模板共存,并且函数模板实例化为和模板函数具有相同类型参数函数函数调用时,若匹配度相同,将优先调用模板函数。...2.也可以通过将数组字符串长度作为非类型模板参数,定义可以适配不同长度裸数组字符串常量模板。...实际应用时,可以根据函数作用加以选择,若要比较大小,一般是按照引用传递;若是比较参数类型是否相同,则可以是按值传递。 7.5 处理返回值 1.函数返回值也可以是按值返回按引用返回。...实例化:查找到最匹配模板后,根据实参从模板创建出常规类函数过程。 特例化:模板部分全部参数进行特化,定义新模板过程。...十八、模板多态性 18.1 动态多态 动态多态:通过继承和虚函数实现,在运行期根据指针引用具体类型决定具体调用那一个虚函数

6.5K63

《C++Primer》第十六章 模板与泛型编程

compare(const char (&p1)[3], const char(&p2)[4]) 非类型参数可以是一个整型,或者是一个指向对象或者函数类型指针(左值)引用 绑定到非类型参数实参必须是一个常量表达式...类型转换与模板类型参数 能在调用中应用于函数模板包括如下三项: 顶层const无论是在形参中还是在实参中都会被忽略 const转换:可以将一个const对象引用(指针)传递给一个const引用...转发 某些函数需要将其一个多个实参联通类型不变地转发给其他参数,这种情况我们需要保持被转发实参所有性质: 实参类型是不是const 实参是左值还是右值 看一下这个例子,我们编写一个函数接受一个可调用表达式和两个额外实参...多个可行模板 当多个重载模板一个调用提供同样好匹配时,应选择最特例化版本。 3. 模板模板重载 对于一个调用,如果一个函数模板与一个函数模板提供同样好匹配,则选择模板版本。 4....转发参数包 可变参数函数通常将它们参数转发给其他函数,这种函数通常与我们emplace_back函数具有一样形式: // fun有零个多个参数, 每个参数都是一个模板参数类型右值引用 template

1.7K10

C++函数模板详解

具体操作 关键字template 总是放在模板定义与声明最前面关键字后面是用逗号分隔模板参数表(template parameter list)它用尖括号 一个小于号和一个大于号括起来列表是模板参数表不能为空模板参数可以是一个模板类型参数...(template typeparameter)它代表了一种类型也可以是一个模板类型参数(template nontype parameter)它代表了一个常量表达式模板类型参数由关键字class ...模板类型参数由一个普通参数声明构成模板类型参数表示参数名代表了一个潜在值而值代表了模板定义中一个常量例如size 是一个模板类型参数它代表arr 指向数组长度 template Type...函数定义声明跟在模板参数表后除了模板参数是类型指示符常量值外函数模板定义看起来与模板函数定义相同 template Type min( const Type (&r_array)[size]...min()决定记住一个函数两种用法是调用它和取它地址 当一个名字被声明为模板参数之后它就可以被使用了一直到模板声明定义结束为止模板类型参数被用作一个类型指示符可以出现在模板定义余下部分它使用方式与内置或用户定义类型完全一样比如用来声明变量和强制类型转换模扳非类型参数被用作一个常量值可以出现在模板定义余下部分它可以用在要求常量地方或许是在数组声明中指定数组大小作为枚举常量初始值

96370

const 使用总结

它可以用于任何函数或者类之后全局namespace变量,也可以用于文件、函数、块作用域、类中static变量,也可以用于修饰成员函数函数参数、模板参数。...);// 调用是第一个函数fun(obj2);// 调用是第二个函数上面的代码中,根据实参是否是常量对象来调用相应函数,当使用常量实参调用fun函数时,只能匹配到const版本那个函数,当使用非常量实参调用...,我们通过成员函数是否有const来进行重载,这样,常量对象只能调用常量成员函数,非常量对象既可以调用常量成员函数也可以调用常量成员函数,但是对于非常量成员函数更加匹配,所以会调用常量成员函数,我们可以定义两个重载函数...,编译器利用实参来推断出模板实参,根据模板实参来生成一个函数实例。...跟模板函数不一样是,模板函数一般不会进行类型转换,而是直接生成另外一个模板实例。但是对于const是个例外,它允许const进行类型转换。

7610

【笔记】《深入理解C++11》(下)

C++11时候: 函数体只能有单一return语句(或者额外不影响数据编译期语句) 函数必须返回值, 因为一定要从常量表达式中获得常量 函数使用前(编译期)一定要有定义 返回语句中不能有非常量函数数据...注意此时类构造函数函数体必须为空, 所有成员都只能依靠常量表达式在初始化列表中初始化 常量表达式不能用于virtual 常量表达式函数不需要重写非常量版本, 编译器会自动生成, 重写反而会报错 当模板函数声明为常量表达式后...模板类型后面的三个点...称为模板参数包, 模板参数包也可以是特化 推导后模板参数包再通过参数名称后三个点...来进行解包(包扩展) 变长模板自然也可以用在函数模板中, 称为函数参数包....等设计 nullptr且仅可隐式转换为任何一种指针类型 nullptr无论如何都不能被转换为指针类型, 不能用于算术表达式 nullptr可以用于关系比较, 但仅能与nullptr比较, 返回true..., 描述函数参数是如何压入栈和由谁平衡栈约定, 直接将其写在函数名和返回值之间位置 平衡栈: 函数返回时由谁负责将压入栈函数参数清除 函数调用过程: 根据调用约定把函数参数压栈存入寄存器 跳转到函数代码

1K30

C++ primer里template用法

同种结构不同实例,也许只在数据元素     类型数量上略有差异,如果每个实例都重新定义,则非常麻烦且容易出错。那么能     否同种类型数据结构仅定义一次呢?...类型参数和     常量参数可以是任何合法标准类型和用户自定义类型,包括简单类型及各种结构体。...另外,与模板类不同是,必须将     函数实现包括在调用每个源文件中,使编译器能从函数实现产生代码。...通常做法是     将模板函数实现也放在定义该类头文件中,这样只需在调用源文件中包含头文     件即可。     那么,如何使用生成特定类实例呢?...堆栈操作     都是通过类成员函数来实现。使用具体步骤如下:     1. 在要使用堆栈类程序代码文件开头包括模板类及其成员函数定义。     2.

1.3K50

C++复习笔记——C++ 关键字

export 为了访问其他编译单元(如另一代码文件)中变量对象,普通类型(包括基本数据类、结构和类),可以利用关键字 extern,来使用这些变量对象时;但是模板类型,则必须在定义这些模板类对象和模板函数时...const const(常量,constant)所修饰对象变量不能被改变,修饰函数时,该函数不能改变在该函数外面声明变量也不能调用任何const函数。...静态变量静态函数,只有本文件内代码才访问它,它名字(变量名函数名)在其它文件中不可见。因此也称为"文件作用域"。...只能用于类静态和非常量数据成员。由于一个对象状态由对象静态数据成员决定,所以随着数据成员改变,对像状态也会随之发生变化。...如果一个类成员函数被声明为 const类型,表示该函数不会改变对象状态,也就是该函数不会修改类静态数据成员

1.3K30

【笔记】《深入理解C++11》(上)

没有继承关系) 类中第一个静态成员类型要与基类不同(为了类指针能直接指向第一个成员) 没有虚函数和虚基类 所有静态成员都满足POD布局(递归定义) 之所以C++11引入POD概念是为了保证我们可以安全地用...最终可以用is_pod::value直接判断是否POD 受限联合 C++11后, 任何引用类型都可以成为union成员(包括函数), 因此称为受限联合 不允许静态成员变量存在 union一些默认函数将被删除..., 例如当存在POD成员且这个成员平凡构造函数时, 这个union默认构造将被删除 匿名union对外是开放, 因此放在类声明中可以按照构造函数不同而初始化为不同类型, 此时类被称为枚举式类...函数模板根据我们实参类型调用时进行特化并实例化, 具体来说匹配遵循以下步骤: 首先对于一次调用, 编译器查找所有具有此名称函数和实例化模板函数表 在这些函数中进行比较, 将不可行函数剔除,..., 需要泛型时候还是应该用模板处理 auto禁止结构体中静态成员进行推导 不允许声明auto数组 新增range-for语法要求目标有begin和end函数, 且支持++和==, 常与auto

1.8K20

终于弄明白了万能引用和右值引用区别

,这些型别包括 std::unique_ptr std::future和std::thread等 2,完美转发:使人们可以撰写接受任意实参函数模板,并转发到其他函数,目标函数会接受到与转发函数所接受完全相同实参...两种含义: 1, 右值引用,仅仅会绑定到右值,识别出移动对象 2,万能引用,可以是左值引用 T&,也可以是右值引用, 也可以绑定到 const对象 volatile对象两者对象 */ //右值引用...,在具现过程中,和几乎任何实参型别都会产生精确匹配,一旦万能引用成为重载候选 //它就会吸引大批实参型别 //实现4: //如何解决:撰写一个带完美转发构造函数 //实现4: //如何解决:撰写一个带完美转发构造函数..."); //Person pp(p); /** 调用是 forward版本 非常量左值 p 被初始化,模板构造函数可以实例化来接受 Person型别的非常量左值形参...//如果万能引用仅是形参列表一部分,列表中还有其他万能引用型别的形参的话,那么只要万能引用形参 //具备充分差匹配能力,则它就足以将这个带有万能引用形参重载版本踢出局 //改造 e26 中函数

1.7K10

C++ 特性使用建议

但是缺省参数函数调用代码难以呈现所有参数,开发者只能通过查看函数申明定义确定如何使用API,当缺省参数不适用于新代码时可能导致重大问题。...编译器可以更好地进行类型检测,相应地,也能生成更好代码。人们编写正确代码更加自信,因为他们知道所调用函数被限定了能不能修改变量值。即使是在无锁多线程编程中,人们也知道什么样函数是安全。...访问函数应该总是 const。其他不会修改任何数据成员,未调用 const 函数,不会返回数据成员 const 指针引用函数也应该声明成 const。...(3)如果数据成员在对象构造之后不再发生变化,可将其定义为 const。 13.constexpr 用法 在C++11 里,用 constexpr 来定义真正常量实现常量初始化。...考虑一下你们团队成员平均水平是否能够读懂并且能够维护你写模板代码。或者一个C++ 程序员和一些只是在出错时候偶尔看一下代码的人能够读懂这些错误信息或者能够跟踪函数调用流程。

1.6K20

C++:19---重载与模板模板特例化

一、重载与模板 函数模板可以被另一个模板一个普通模板函数重载 如果涉及函数模板,则函数匹配规则会有以下约束: 如果同样好函数中只有一个是非模板函数,则选择此函数 如果同样好函数中没有模板函数...③可行函数模板模板)按类型转换(如果对此调用需要的话)来排序。...debu_rep实例化而来 但是根据重载函数模板特殊规则,此调用解析被解析为debug_rep(T*),因此调用是第二个版本debu_rep 原因在于:debug_rep(const T&)本质上可以用于任何类型...在某些情况下,通用模板定义特定类型是不适合:通用定义可能编译失败做得不正确。...因此我们需针对类函数定义一个特例化版本 下面是两个模板: //第一版本:可以比较任意两个类型templateint compare(const T&, const T&);/

1.3K20

【笔记】《C++Primer》—— 第16章:模板与泛型编程

,非类型参数表示是一个值而不是类型,因此非类型参数在编译时会被用户提供编译器推断一个常量代替,从而允许我们初始化数组之类 非类型参数可以是整型指向对象函数指针左值引用,但是注意绑定到非类型整型必须是常量表达式...模板程序应该尽量减少实参类型要求,例如比较大小时尽量使用小于号甚至使用less函数比较 编译器在模板实例化(被输入具体参数引用)时才生成代码 为了生成实例化模板,便因此需要掌握函数模板模板成员函数定义...,在模板实参推断过程中,编译器用函数调用实参类型来查找哪些函数版本最为匹配 对于函数模板与普通模板函数不太一样,编译器通常不对实参进行类型转换从而只有几个类型转换会应用在实参上,编译器偏向于生成新模板实例来适配...当函数指针调用存在歧义时,我们可以显式指定指针类型来消歧义 具体来说编译器是如何模板函数调用中推断具体实参类型呢,要分为几种情况 当函数参数是普通左值时,正常推断,很多参数无法传递进去 当函数参数是左值引用如...然后再用得到信息正确参数传递给其他函数,这就是转发操作 16.3 重载与模板 函数模板可以被另一个模板模板函数重载,与平时一样名字相同函数需要参数不同才能重载 但是对于函数模板来说,实参调用函数会是重载版本中哪一个需要按照以下规则来判断

1.5K30

C++特性使用建议

但是缺省参数函数调用代码难以呈现所有参数,开发者只能通过查看函数申明定义确定如何使用API,当缺省参数不适用于新代码时可能导致重大问题。...编译器可以更好地进行类型检测,相应地,也能生成更好代码。人们编写正确代码更加自信,因为他们知道所调用函数被限定了能不能修改变量值。即使是在无锁多线程编程中,人们也知道什么样函数是安全。...访问函数应该总是 const。其他不会修改任何数据成员,未调用 const 函数,不会返回数据成员 const 指针引用函数也应该声明成 const。...如今 constexpr 就可以定义浮点式真・常量,不用再依赖字面值了;也可以定义用户自定义类型常量;甚至也可以定义函数调用所返回常量。 14.整型 C++ 内建整型中,仅使用 int。...考虑一下你们团队成员平均水平是否能够读懂并且能够维护你写模板代码。或者一个C++ 程序员和一些只是在出错时候偶尔看一下代码的人能够读懂这些错误信息或者能够跟踪函数调用流程。

1.9K30

Google C++ 编程风格指南(五):其他 C++ 特性

右值引用能实现移动但不可拷贝类型, 这一特性那些在拷贝方面没有实际需求, 但有时又需要将它们作为函数参数传递塞入容器类型很有用....结论: 简单数值 (对象), 两种都无所谓. 迭代器和模板类型, 使用前置自增 (自减). 5.12. const 用法 我们强烈建议你在任何可能情况下都要使用 const....编译器可以更好地进行类型检测, 相应地, 也能生成更好代码. 人们编写正确代码更加自信, 因为他们知道所调用函数被限定了能不能修改变量值....其他不会修改任何数据成员, 未调用 const 函数, 不会返回数据成员 const 指针引用函数也应该声明成 const....考虑一下你们团队成员平均水平是否能够读懂并且能够维护你写模板代码.或者一个c++ 程序员和一些只是在出错时候偶尔看一下代码的人能够读懂这些错误信息或者能够跟踪函数调用流程.

1.1K30

整理了70道C语言与C++常见问答题

,其构成元素既可以是基本数据类型变量,也可以是一些复合型类型数据。...许多实际计算机系统基本类型数据在内存中存放位置有限制,它们会要求这些数据首地址值是某个数k(通常它为48)倍数,而这个k则被称为数据类型对齐模数。...「注意」:无论是指针常量还是常量指针,其最大用途就是作为函数形式参数,保证实参在被调用函数不可改变特性。 27 如何避免“野指针” 指针变量声明时没有被初始化。...定义」单一模板提供一个特殊实例,它将一个多个模板参数绑定到特定类型值上 (1)模板函数特例化 必须为原函数模板每个模板参数都提供实参,且使用关键字template后跟一个空尖括号,表明将原模板所有模板参数提供实参...70 STL线程不安全情况 在对同一个容器进行多线程读写、写操作时; 在每次调用容器成员函数期间都要锁定容器; 在每个容器返回迭代器(例如通过调用beginend)生存期之内都要锁定容器

3K01

【Example】C++ Template (模板)概念讲解及编译避坑

定义模板关键字就是 template,语法: template or template template 函数声明定义进行修饰,其中 T 可以是任意名字...进行在模板函数调用时,编译器会根据变量类型推断函数参数类型。 那么,函数模板是否可以支持多种类型呢?可以!...2,类模板 函数模板很好理解,那么类模板是什么呢? 可以在类模板内部外部定义成员函数。 如果在类模板外部定义成员函数,则会像定义函数模板一样定义它们。...成员函数以是函数模板,并指定附加参数。 ...然后:类模板当中非类型形参 这是一个什么东西呢? 1,它是一个常量。 2,它类型只能是 int 、指针、引用这三种内置类型。 3,调用只能是一个常量表达式。 它使用场景?

65220

C++11新特性学习笔记

如下: decltype(expression) variable_name; 在上面的代码中,expression是需要推导表达式,variable_name是根据表达式推导出数据类型命名变量名...这些类特殊成员函数负责创建、初始化、销毁,或者拷贝类对象。如果程序员没有显式地为一个类定义某个特殊成员函数,而又需要用到特殊成员函数时,则编译器会隐式为这个类生成一个默认特殊成员函数。...l 参数(右值)不可以是常量,因为我们需要修改右值。 l 参数(右值)资源链接和标记必须修改,否则,右值析构函数就会释放资源,转移到新对象资源也就无效了。...这个函数定义次数对于程序员来说,是非常低效。 那C++11是如何解决完美转发问题呢?...C++11中,新增加了一个std::function类模板,它是C++中现有的可调用实体一种类型安全包裹。

2K20

C++11新特性学习笔记

如下: decltype(expression) variable_name; 在上面的代码中,expression是需要推导表达式,variable_name是根据表达式推导出数据类型命名变量名...这些类特殊成员函数负责创建、初始化、销毁,或者拷贝类对象。如果程序员没有显式地为一个类定义某个特殊成员函数,而又需要用到特殊成员函数时,则编译器会隐式为这个类生成一个默认特殊成员函数。...l 参数(右值)不可以是常量,因为我们需要修改右值。 l 参数(右值)资源链接和标记必须修改,否则,右值析构函数就会释放资源,转移到新对象资源也就无效了。...这个函数定义次数对于程序员来说,是非常低效。 那C++11是如何解决完美转发问题呢?...C++11中,新增加了一个std::function类模板,它是C++中现有的可调用实体一种类型安全包裹。

2.2K20
领券