当前位置:首页 > 数码 > 深化探求模板编程的精华-从类型参数到智能推导-模板的艺术-C-把握 (深化探求模板范文)

深化探求模板编程的精华-从类型参数到智能推导-模板的艺术-C-把握 (深化探求模板范文)

admin9个月前 (04-14)数码50

类型模板参数

在示例中,模板有一个模板参数:存储在网格中的类型。编写类模板时,您须要在尖括号内指定参数列表,例如:

这个参数列表相似于函数或方法中的参数列表。与函数和方法一样,你可以编写具备恣意多个模板参数的类。此外,这些参数不用是类型,它们可以有自动值。

非类型模板参数

非类型参数是个别参数,如整数和指针——这类参数你或者曾经在函数和方法中很相熟了。但是,非类型模板参数只能是整型(、、等)、枚举类型、指针、援用、 std::nullptr_t 、、和。C++20还准许浮点类型和类类型的非类型模板参数。后者有很多限度,在本文中不再具体讨论。

在类模板中,你可以经常使用非类型模板参数来指定网格的高度和宽度,而不是在结构函数中指定。在模板列表中指定非类型参数而不是在结构函数中指定的关键好处是这些值在代码编译之前就已知。回顾一下,编译器经过在编译之前交流模板参数来生成模板实例的代码。因此,你可以在成功中经常使用个别的二维数组,而不是灵活调整大小的向量数组。以下是带有更改的新类定义:

exporttemplate<typenameT,size_tWIDTH,size_tHEIGHT>classGrid{public:Grid()=default;virtual~Grid()=default;//明白自动复制结构函数和赋值运算符。Grid(constGrid&src)=default;Grid&operator=(constGrid&rhs)=default;std::optional<T>&at(size_tx,size_ty);conststd::optional<T>&at(size_tx,size_ty)const;size_tgetHeight()const{returnHEIGHT;}size_tgetWidth()const{returnWIDTH;}private:voidverifyCoordinate(size_tx,size_ty)const;std::optional<T>m_cells[WIDTH][HEIGHT];};

留意,模板参数列表须要三个参数:存储在网格中的对象类型,以及网格的宽度和高度。宽度和高度用于创立存储对象的二维数组。上方是类方法的定义:

//类方法定义template<typenameT,size_tWIDTH,size_tHEIGHT>voidGrid<T,WIDTH,HEIGHT>::verifyCoordinate(size_tx,size_ty)const{if(x>=WIDTH){throwstd::out_of_range{std::format("{}mustbelessthan{}.",x,WIDTH)};}if(y>=HEIGHT){throwstd::out_of_range{std::format("{}mustbelessthan{}.",y,HEIGHT)};}}template<typenameT,size_tWIDTH,size_tHEIGHT>conststd::optional<T>&Grid<T,WIDTH,HEIGHT>::at(size_tx,size_ty)const{verifyCoordinate(x,y);returnm_cells[x][y];}template<typenameT,size_tWIDTH,size_tHEIGHT>std::optional<T>&Grid<T,WIDTH,HEIGHT>::at(size_tx,size_ty){returnconst_cast<std::optional<T>&>(std::as_const(*this).at(x,y));}

留意,之前你在哪里指定了,如今你必定指定来指定三个模板参数。你可以这样实例化并经常使用这个模板:

Grid<int,10,10>myGrid;Grid<int,10,10>anotherGrid;myGrid.at(2,3)=42;anotherGrid=myGrid;cout<<anotherGrid.at(2,3).value_or(0);

这段代码看起来很棒,但可怜的是,存在比你最后预期的更多限度。首先,你不能经常使用十分量整数来指定高度或宽度。以下代码无法编译:

size_theight{10};Grid<int,10,height>testGrid;//无法编译

但是,假设你将高度定义为常量,则可以编译:

constsize_theight{10};Grid<int,10,height>testGrid;//可编译并上班

具备正确前往类型的函数也可以上班。例如,假设你有一个前往的函数,你可以用它来初始化高度模板参数:

constexprsize_tgetHeight(){return10;}...Grid<double,2,getHeight()>myDoubleGrid;

第二个限度或者更关键。如今宽度和高度是模板参数,它们是每个网格类型的一局部。这象征着和是两种不同的类型。你不能将一种类型的对象赋值给另一种类型的对象,也不能将一种类型的变量传递给希冀另一种类型变量的函数或方法。

类模板参数的自动值

设置高度和宽度的自动值

假设您继续经常使用高度和宽度作为模板参数的方法,您或者想为类结构函数中之前的高度和宽度非类型模板参数提供自动值。C++准许您经常使用相似的语法为模板参数提供自动值。同时,您也可认为类型参数提供自动值。上方是类定义:

exporttemplate<typenameT=int,size_tWIDTH=10,size_tHEIGHT=10>classGrid{//其他局部与之前版本相反};

在方法定义的模板规范中,您不须要为、和指定自动值。例如,这是方法的成功:

template<typenameT,size_tWIDTH,size_tHEIGHT>conststd::optional<T>&Grid<T,WIDTH,HEIGHT>::at(size_tx,size_ty)const{verifyCoordinate(x,y);returnm_cells[x][y];}

如今,您可以在没有任何模板参数的状况下实例化,只要指定元素类型,元素类型和宽度,或元素类型、宽度和高度:

Grid<>myIntGrid;Grid<int>myGrid;Grid<int,5>anotherGrid;Grid<int,5,5>aFourthGrid;

请留意,假设您不指定任何类模板参数,您依然须要指定一组空的尖括号。例如,以下代码无法编译!

GridmyIntGrid;

类模板参数列表中自动参数的规定与函数或方法相反;也就是说,您可以从左边开局为参数提供自动值。

类模板参数推导(CTAD)

智能推导模板参数

类模板参数推导准许编译器智能从传递给类模板结构函数的参数推导出模板参数。例如,规范库中有一个名为的类模板,在中定义,并在第1章中引见。存储两个或者不同类型的值,通常须要指定为模板参数。例如:

pair<int,double>pair1{1,2.3};

为了防止编写模板参数,可以经常使用一个名为 std::make_pair() 的辅佐函数模板。编写自己的函数模板的细节将在本章前面讨论。函数模板不时支持基于传递给函数模板的参数智能推导模板参数。因此, make_pair() 能够依据传递给它的值智能推导出模板类型参数。例如,编译器为以下调用推导出:

autopair2{make_pair(1,2.3)};

经常使用类模板参数推导(CTAD),不再须要这样的辅佐函数模板。编译器如今会依据传递给结构函数的参数智能推导出模板类型参数。关于类模板,您可以方便地编写以下代码:

pairpair3{1,2.3};//pair3的类型为pair<int,double>

当然,这仅在类模板的一切模板参数要么具备自动值,要么用作结构函数中的参数,从而可以推导进去时才有效。请留意,CTAD要求有一个初始化器能力上班。以下是合法的:

pairpair4;

许多规范库类支持CTAD,例如、等。

用户定义的推导指南

您也可以编写自己的用户定义推导指南来协助编译器。这些指南准许您编写模板参数如何被推导的规定。这是一个初级主题,所以不会具体讨论,但会给出一个示例来展现它们的弱小配置。假定您有以下 SpreadsheetCell 类模板:

template<typenameT>classSpreadsheetCell{public:SpreadsheetCell(Tt):m_content{move(t)}{}constT&getContent()const{returnm_content;}private:Tm_content;};

经常使用智能模板参数推导,您可以创立一个 std::string 类型的 SpreadsheetCell

stringmyString{"HelloWorld!"};SpreadsheetCellcell{myString};

但是,假设您将 constchar* 传递给 SpreadsheetCell 结构函数,则类型被推导为 constchar* ,这不是您想要的!您可以创立以下用户定义的推导指南,当向结构函数传递 constchar* 作为参数时,使其将推导为 std::string

SpreadsheetCell(constchar*)->SpreadsheetCell<std::string>;

这个指南必定在类定义

之外但在与 SpreadsheetCell 类相反的命名空间内定义。通用语法如下。关键字是可选的,其行为与结构函数的相反。通常,这样的推导指南也是模板。

explicitTemplateName(Parameters)->DeducedTemplate;

请C++高手指导 IntelliSense: 缺少 类模板 "std::iterator" 的参数列表 。如何添加类模板到集成环境

std::vector<char>::iterator q;//char替换成你需要的参数类型,q替换成你的迭代器名,不在前面在using,写在main函数前面,试试看

新手如何学习编程?

C

学编程入门建议:1.学编程要从根本出发,从理论上来说,需要广泛的阅读。 了解算法的博大精深和计算机的基本理论。 2.从实践上来说,需要有广泛的练习,练习的广泛在于练习不同的内容。 然后就是创新精神和数学思维能力,这些都是需要培养的。 基础要打好学编程要具备一定的基础。 3.逻辑思维能力的培养、学程序设计要有一定的逻辑思维能力。 “思维能力”的培养要长时间的实践锻炼。 要想成为一名优秀的程序员,最重要的是掌握编程思想。 要做到这一点必须在反复的实践、观察、分析、比较、总结中逐渐地积累。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: C

“深化探求模板编程的精华-从类型参数到智能推导-模板的艺术-C-把握 (深化探求模板范文)” 的相关文章

编程实践-哈希负载均衡算法-IP-C (编程实践心得体会)

编程实践-哈希负载均衡算法-IP-C (编程实践心得体会)

Nginx 是一个高性能的开源 Web 服务器和反向代理服务器,因其高效处理高并发的请求而闻名。以下是一些 Nginx 用于处理高并发的主要特点和技术: 事件驱动架构: Nginx 使...

揭秘性能与并发的机密-C-多线程编程 (性能与什么有关)

揭秘性能与并发的机密-C-多线程编程 (性能与什么有关)

当天咱们将深化讨论C++中的多线程编程,提醒多线程如何解锁性能后劲,提高程序的并发性能。 什么是多线程? 在计算机迷信中,多线程是指一个进程(程序的口头实例)中的多个线程同时口头。每个...

让新手也能轻松把握-C-类模板特化与承袭经常使用指南 (请问新手)

让新手也能轻松把握-C-类模板特化与承袭经常使用指南 (请问新手)

一、类模板特化 1.特化的成功 你可以为特定类型提供类模板的替代成功。例如,你或许以为constchar类型(C格调字符串)的Grid行为没无心义。Grid<constchar&...

的区别-中-C-math.h-和-cmath (的区别中的钱)

的区别-中-C-math.h-和-cmath (的区别中的钱)

一、引言 C++规范库中的<cmath>和C言语规范库中的<math.h>均为数学函数库,它们提供了一系列数学函数和常量。但是,这两者之间存在一些关键的区别...

监禁程序后劲的优化利器-C-中的内联函数 (监禁等于坐牢吗)

监禁程序后劲的优化利器-C-中的内联函数 (监禁等于坐牢吗)

一、内联函数的定义和特点 内联函数是一种不凡的函数,它经过在编译时将函数调用交流为函数体中的代码,以缩小函数调用的开支,从而提高程序的口头效率。内联函数通罕用于那些函数体较小、调用频繁的场景...

与设计形式-可裁减的代码-C-打造可保养 (设计与形式的关系)

与设计形式-可裁减的代码-C-打造可保养 (设计与形式的关系)

引言 C++是一种弱小的编程言语,它提供了许多工具和库以支持面向对象编程和通用编程。设计形式是一种用于处置特定疑问的经过验证的处置打算。C++的灵敏性和设计形式的广泛...

深入学习-C-掌握内存管理的艺术 (深入学习习总书记系列讲话精神)

深入学习-C-掌握内存管理的艺术 (深入学习习总书记系列讲话精神)

简介 内存管理是学习任何编程语言的必备知识,C++也不例外。C++ 是一门功能强大、底层控制能力强的编程语言,尤其适用于系统级开发、游戏开发和嵌入式系统等领域。与一些更简单的编程语言相比,学...