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

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

模板程序应该尽量减少对实参类型要求,例如比较大小时尽量使用小于号甚至使用less函数比较 编译器在模板实例(被输入具体参数引用)时才生成代码 为了生成实例模板,便因此需要掌握函数模板或类模板成员函数定义...16.1.5-16.1.6 控制实例&效率与灵活性 模板在被使用时才会实例,这意味着当多个独立编译文件用了同样模板时,相同实例可能会被实例在多个对象文件,这会造成资源浪费。...unique_ptr为了性能,将删除器类型模板参数传入,编译时绑定,这样之后使用时候可以直接调用实例删除器,但是无法在实例后更改删除器了 16.2 模板实参推断 从函数实参确定模板实参过程称为模板实参推断...,在模板实参推断过程,编译器用函数调用实参类型查找哪些函数版本最为匹配 对于函数模板与普通非模板函数不太一样,编译器通常不对实参进行类型转换从而只有几个类型转换会应用在实参上,编译器偏向于生成新模板实例适配...当函数指针调用存在歧义时,我们可以显式指定指针类型消歧义 具体来说编译器是如何模板函数调用推断具体实参类型呢,要分为几种情况 当函数参数是普通左值时,正常推断,很多参数无法传递进去 当函数参数是左值引用如

1.5K30

C++17常用新特性(十一)---折叠表达式

从C++17开始,可以使用二元操作符对形参包参数进行计算,这一特性主要针对可变参数模板进行提升。支持二元操作符多达32个。例如,下面的函数将会返回传入所有的参数和。...1 折叠表达式缘起 折叠表达式对编程直接影响为:在使用递归进行实例函数参数模板场景可以直接使用折叠表达式使用后代码更加清晰也更加简便。...函数执行顺序都是从左向右。 上面是将折叠应用在函数,下面将讨论将折叠使用在类,作为类基类进行调用。...折叠基类函数调用 敲黑板了,折叠使用场景越来越复杂了,不过也可以给我们编码带来便利,将其应用在基类可以调用具有可变参数基类成员函数。...2.3 使用折叠处理类型 通过使用类型特征,可以判断类或者函数传入参数类型是否相同。实现方式如下: template<typename T1, typename...

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

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

当一个模板实例化时,非类型参数被一个用户提供或者编译器推断出来值锁替代,这些纸必须是常量表达式,从而允许编译器在编译时实例模板。...控制实例 前面我们提到只有当模板使用时才会进行实例,这一特性意味着相同实例可能出现在多个对象文件。...在本例,我们可以使用remove_reference获得元素类型。remove_reference模板有一个模板类型参数和一个名为typepublic类型成员。...否则 XT 4.函数指针和实参推断 当我们用一个函数模板初始一个函数指针或者为一个函数指针赋值时,编译器使用指针类型推断模板实参。...这样就不必担心编译器由于未遇到你希望调用函数实例一个并非你需要版本。 可变参数模板 一个可变参数模板variadic template就是一个接受可变数组参数模板函数模板类。

1.8K10

《重构-代码整洁之道TypeScript版》第2天

) [x] Collapse Hierarchy(折叠继承体系) [ ] Consolidate Conditional Expression(合并条件表达式) [ ] Consolidate Duplicate...:在分布系统和并发系统,不可变值对象特别有用,因为你无需考虑他们同步问题。...如果不是,我们就用不到使用本项重构,因为可变值会造成凡人别名问题。...//如上RMB显然是不可变币种 所以我们可以把它改成值类型 //有2种方式可以改变他为值类型 一种是设计模式里单例 // 我们这里按照原书逻辑添加了一个equal函数 export interface...:从一个类衍生出许多彼此相等实例,希望将他们替换为同一对象。 动机?:许多系统,像日期、数量、名称等他们完全由所含意义标识,你并不在乎他们有多少副本。

66110

【笔记】《C++Primer》—— 第三部分:类设计者工具

模板不会推断参数类型模板成员函数只有在使用时才会实例模板与另一个模板直接最常见友元是一对一友元,首先模板需要声明所有需要用到名字,然后在声明友元时标注出目标类具体模板实参 类模板也可以一对多友元...与函数模板与普通非模板函数不太一样,编译器通常不对实参进行类型转换从而只有几个类型转换会应用在实参上,编译器偏向于生成新模板实例适配 如果显式指定了实参类型,那么就可以自动正常进行类型转换 有时我们需要使用编译确定下参数类型来作为返回值类型...16.2有详细介绍 如果我们通过类型别名或模板参数之类方法间接定义了引用引用(正常情况下无法定义),会产生引用折叠”,(X&)&,(X&)&&,(X&&)&都折叠为X&,(X&&)&&折叠为X...forward函数,能恢复被右值引用参数去除右值引用属性 在没有歧义情况下,永远会调用发生了最少改变,最精确匹配,最不需要调用自定义类型转换,最不需要调用模板那个重载,即“更特例可变参数模板就是一个能接受数目可变类型可变参数类...即使我们需要特例所有的类型参数也要保留一个空尖括号做标记 完全模板特例本质是模板一个实例,而不是重载,因此特例不会影响函数匹配。

1.7K10

浅谈 C++ 元编程

实例 (instantiation) 类似于函数 绑定 (binding),是编译器根据参数个数和类型,判断使用哪个重载过程。...而 C++ 17 提出了 折叠表达式 (fold expression) 语法,化简了迭代写法。 2.2.1 定长模板迭代 代码展示了如何使用 编译时迭代 实现编译时计算阶乘(N!)。...4.2 实例错误 模板实例函数绑定 不同:在编译前,前者对传入参数是什么,没有太多限制;而后者则根据函数声明,确定了应该传入参数类型。...而对于模板实参内容检查,则是在实例过程完成。所以,程序设计者在编译前,很难发现实例化时可能产生错误。...具体思路是,将不同参数实例得到模板 相同部分 抽象为一个 基类 (base class),然后 “继承” 并 “重载” 每种参数情况 不同部分,从而实现更多代码共享。

2.9K60

C++17常用新特性

2 C++17新特性 2.1 折叠表达式 从C++17开始,可以使用二元操作符对形参包参数进行计算,这一特性主要针对可变参数模板进行提升,可以分为左折叠和右折叠。支持二元操作符多达32个。...对模板进行实例化时,不需要指定模板参数,编译器会根据传入实参进行类型推导。...2.3 用auto作为非类型模板参数 在模板参数中使用auto作为关键字时,模板实例传入非类型值,auto可以推导出参数类型。...不过这一特性在C++20已经被支持进来。C++17支持类型包括:左值引用,整数,指针类型,成员指针类型,枚举。...2.5 inline 可以将变量定义成为内联变量,内联变量不能用户函数定义使用时避免重复定义。

2.1K20

C++进阶:C++11(列表初始、右值引用与移动构造移动赋值、可变参数模版...Args、lambda表达式、function包装器)

完美转发通常与模板和引用折叠相关联,并在实现泛型代码时非常有用。 引用折叠: 引用折叠是 C++11 一个规则,用于确定引用最终类型。...虽然底层很难,但是我们用起来舒服 可变参数模板是 C++11 引入一个特性,允许函数模板接受任意数量参数。...在 C++ 可变参数模板通常使用模板参数包(template parameter pack)实现。...我们无法直接获取参数包args每个参数,只能通过展开参数包方式获取参数包每个参数,这是使用可变模版参数一个主要特点,也是最大难点,即如何展开可变模版参数。...C++function本质是一个类模板,function可以封装他们,目标是统一类型,统一后我们能传给各种容器使用函数指针的话类型复杂、仿函数类型不同、Lambda表达式没有类型

5900

【C++修炼之路】30.可变参数模板&&包装器

C++11新特性可变参数模板能够创建可以接受可变参数函数模板和类模板,相比C++98/03,类模版和函数模版只能含固定数量模版参数,可变模版参数无疑是一个巨大改进。...我们无法直接获取参数包args每个参数,只能通过展开参数包方式获取参数包每个参数,这是使用可变模版参数一个主要特点,也是最大难点,即如何展开可变模版参数。...Args> void ShowList(Args... args) { //逗号表达式:结果为后面的值,通过可变参数列表展开并推演个数,进行实例调用上面的函数。......Args> void ShowList(Args... args) { //逗号表达式:结果为后面的值,通过可变参数列表展开并推演个数,进行实例调用上面的函数。...那么func可能是函数名?函数指针?函数对象(仿函数对象)?也有可能是lamber表达式对象?所以这些都是可调用类型!如此丰富类型,可能会导致模板效率低下! //为什么呢?

26720

C++ 学习笔记

2.类模板成员函数只有在调用时候才会实例。 2.3 部分使用模板 1.类模板实例化时,模板实参只需要支持被实例部分所有用到操作。...变参类模板和变参表达式 可变参数包可以出现在数学表达式,用于表达式运算。...替换过程可能失败,此时编译器会忽略掉这一替换结果。 替换和实例不同,替换只涉及函数函数模板参数类型及返回类型,最后编译器选择匹配程度最高函数模板进行实例。...11.5 推迟计算 可以通过模板延迟表达式计算,这样模板可以用于不完整类型。...2.Points of Instantiation: 编译器会在需要实例模板地方插入实例点(POI) 14.4 几种实现方案 14.5 显式实例 十五、模板实参推导 15.1 推导过程 1.函数模板实例过程

6.6K63

现代C++之万能引用、完美转发、引用折叠(万字长文)

6.表达式左右值性与类型无关7.引用折叠和完美转发7.1 引用折叠之本质细节7.2 示例与使用7.3 std::move()与std::forward()源码剖析8.不要返回本地变量引用9.总结10...使用会让编译器实例类 std::vector 相应函数。...为了避免编译器对这个代码报错,C++11引入了一个叫做“引用折叠”(reference collapsing)规则来处理某些像模板实例这种情况下带来"引用引用"问题。...我前面已经说过,引用折叠只发生在“像是模板实例这样场景当中”。声明auto变量是另一个这样场景。...引用折叠只会在一些特定可能会产生"引用引用"场景下生效。这些场景包括模板类型推导,auto 类型推导, typedef 形成和使用,以及decltype 表达式

6.2K21

C++11『右值引用 ‖ 完美转发 ‖ 新增类功能 ‖ 可变参数模板

,可以将函数参数类型写为 T&&,因为模板具有自动推导特性,当传入参数为 左值 时,触发 引用折叠 机制,实际参数类型会变为 T&;当传入参数为 右值 时,正常使用 T&& 就行了 这一机制在模板称为...初始列表,其他函数没有这个东西,自然也就不能使用委托构造 4.可变参数 C++11 引入了 可变参数模板可变参数包 特性,允许定义和使用可接受任意数量参数模板函数,这对于编写泛型代码、容器等方面提供了更大灵活性...,C语言中输入输出函数就用到了 可变参数列表 可变参数 意思是你可以随便传入多个 参数,函数都能进行接收,C语言在使用 可变参数模板 时需要依赖 参数数量 + 参数类型 进行识别,简单使用如下 int...这在模板称为 万能引用(引用折叠),既可以引用 左值,也可以引用 右值 可变参数模板 允许传入 任意数量、任意类型 参数 比如下面这几种函数传参都是可以,由此可见 可变参数模板 强大 int...,也可能是其他方面的,这里 上下文 具体指 模板实例和展开时环境和情境 模板 实例和展开可以借助 递归 实现 // 递归推导时结束时调用函数 void showList() {} template

31250

C++11新特性学习笔记

终端:g++ xxx.cpp -std=c++11 类型推导 auto auto自动类型推导,用于从初始表达式推断出变量数据类型。...C 语言中 auto 关键字主要用于自动类型推导,其中变量类型由初始表达式推导,并不能隐式声明为指针或数组类型。 C++ auto 关键字有着更加广泛用法。...返回语句表达式不能使用非常量表达式函数、全局数据,且必须是一个常量表达式 常量表达式构造函数有以下限制: 函数体必须为空 初始列表只能由常量表达式赋值 3.7 用户定义字面量(vs2013...模板改进 5.1 右尖括号>改进 在C++98/03泛型编程模板实例有一个很繁琐地方,就是连续两个右尖括号(>>)会被编译解释成右移操作符,而不是模板参数表形式,需要一个空格进行分割,以避免发生编译时错误...可变参数模板 在C++11之前,类模板函数模板只能含有固定数量模板参数。C++11增强了模板功能,允许模板定义包含0到任意个模板参数,这就是可变参数模板

2K20

C++11新特性学习笔记

终端:g++ xxx.cpp -std=c++11 类型推导 auto auto自动类型推导,用于从初始表达式推断出变量数据类型。...C 语言中 auto 关键字主要用于自动类型推导,其中变量类型由初始表达式推导,并不能隐式声明为指针或数组类型。 C++ auto 关键字有着更加广泛用法。...返回语句表达式不能使用非常量表达式函数、全局数据,且必须是一个常量表达式 常量表达式构造函数有以下限制: 函数体必须为空 初始列表只能由常量表达式赋值 3.7 用户定义字面量(vs2013...模板改进 5.1 右尖括号>改进 在C++98/03泛型编程模板实例有一个很繁琐地方,就是连续两个右尖括号(>>)会被编译解释成右移操作符,而不是模板参数表形式,需要一个空格进行分割,以避免发生编译时错误...可变参数模板 在C++11之前,类模板函数模板只能含有固定数量模板参数。C++11增强了模板功能,允许模板定义包含0到任意个模板参数,这就是可变参数模板

2.2K20

C++17, 语言核心层有哪些新变化?

语言核心层 fold expressions(折叠表达式) C++11 开始支持可变参数模板(即支持任意多数量参数模板).其中任意数量模板参数保存在参数包(parameter pack).在C++...第6行)使用二元运算符是逻辑与(&&).程序输出如下: 对于折叠表达式我想说就是这些,如果你想了解更多细节,可以看看我之前一篇关于折叠表达式文章....结构绑定声明可以简化代码,构造函数模板参数推导同样也可以....Template deduction of constructors(构造函数模板参数推导) 一个函数模板可以通过传递函数参数进行参数类型推导,但这条规则对于一个特殊函数模板却不适用:类模板构造函数...但是25行及26行代码则只能在C++17编译通过,因为在C++17之前,你必须使用尖括号()指定需要实例模板类型参数.

78420

全面盘点17个C++17高级特性

在传统C++,我们通常会这样初始变量: int x; if (condition) { x = 42; } else { x = 24; } 而在C++17,可以使用if初始简化这个过程...折叠表达式 在C++17折叠表达式提供了一种简洁方式,用于对参数包执行二元操作。它们允许在不需要显式递归或迭代情况下执行诸如求和、乘法或连接参数包中元素操作。...total = sum(1, 2, 3, 4, 5); std::cout << "总和: " << total << std::endl; return 0; } 递归sum函数折叠表达式...,我们使用 std::vector 实例化了 foo,将其作为 bob 模板参数。...嵌套命名空间 C++17通过折叠表达式增强了变参模板,使得在处理参数包时代码更为简洁和表达明了。

81010

模板

模板 模板提供参数类型,即能够将类型名作为参数传递给接收方建立类或函数。...当模板被调⽤时, Type将被具体类型值(如int或string)取代。 在模板定义,可以使 ⽤泛型名标识要存储在栈类型。...由于模板不是函数,它们不能单独编译。 模板必须与特定模板实例请求⼀起使⽤。为此,最简单⽅法是将所有模板信息放在⼀个头⽂件,并在要使⽤这些模板⽂件包含该头⽂件。...使用模板类: 仅在程序包含模板并不能⽣成模板类,⽽必须请求实例。 需要声明⼀个类型模板对象,⽅法是使⽤所需具体类型替换泛型名。...- 实例模板时,⽤作表达式参数值**必须是常量表达式**。 - **表达式参数⽅法**使⽤是为⾃动变量维护内存栈。执⾏速度将更快,尤其是在使⽤了很多⼩型数组时。

3K20

C++核心准则F.55 不要使用可变参数

从va_arg读出内容处理假设实际传递数据类型是正确。传递可变参数处理假设数据会按照正确类型被读取。由于通常这两种假设都不能在语言中强制达成安全,只能依靠编程规范以保证其正确。...C++新特性,一个是C++11引入可变参数模板(variadic template),另一个是C++17引入折叠表达式(fold expression)。...定义一个...参数在无法决定实际参数类型时一种有用技术,尤其是定义可以接受任何东西函数以便在重载版本禁止“任何其他东西”或者在模板元程序中表示包罗万象容器。...发起针对以下情况检查:向函数可变参数可变参数传递单独实参,而且不存在在可变参数位置定义了特定数据类型参数重载函数。...修改建议:使用不同函数或者[[抑制((类型准则群组))]] 觉得本文有帮助?

46120

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

初始列表效果总是慢于就地初始, 但也快过在构造函数中进行赋值 注意: 非常量静态变量依然要在头文件外定义从而保证在程序只存在一个 sizeof()可以对类成员表达式使用了 类模板也可以声明友元了...原因和extern变量一样, 普通模板只存在于对应文件.o, 如果一个模板文件被多个文件实例就会产生多份重复代码, 没有extern的话此时重复模板会冲突....有了extern后编译器会自动删除重复实例模板, 不但节省内存还节省了多余实例化时间 注意被其他文件调用外部模板一定要在要用到实例之前实例 局部和匿名成员可以作为模板实参了, 但仍要注意匿名类型声明不能在参数位置...其他构造函数通过带有默认值委派构造调用这个目标构造函数 千万小心环形委派, 会导致编译错误 委派构造函数使得构造函数模板编程也成为一种可能, 通过让模板构造函数成为委派构造函数, 我们可以很容易地接受多种不同类型参数进行相同底层初始...函数模板是根据我们实参类型在调用时进行特化并实例, 具体来说匹配遵循以下步骤: 首先对于一次调用, 编译器查找所有具有此名称函数实例模板函数表 在这些函数中进行比较, 将不可行函数剔除,

1.8K20

听GPT 讲Rust源代码--compiler(29)

这些查询函数接受一些参数,并返回与表达式相关计算结果。 以下是该文件中最常见一些函数及其作用: const_eval_raw: 该函数使用在Rust编译器实现解释器计算常量表达式结果。...UnallowedMutableRefsRaw: 表示在常量表达式使用了不允许原始指针可变引用错误。 NonConstFmtMacroCall: 表示在常量表达式调用了非常量格式错误。...常量表达式可能包含函数调用或者模板参数,而FoundParam 用于追踪这些参数信息,以便在求值过程根据参数值进行计算。...这样,当两个枚举类型实例具有相同判等比较结果时,它们被认为是相等。 此外,该文件还定义了一些辅助函数,用于创建和操作Discriminant类型实例。...它使用Qualifs结构体进行类型检查,并通过StorageDeads记录不可变变量和临时变量死亡状态。 StorageDeads结构体是用于记录不可变变量和临时变量死亡状态结构体。

7310
领券