函数模板参数(函数参数在哪)

C++模板实参的省略下面列举的几种情况不能省略模板实参:1)从模板函数实参表获得的信息有矛盾之处。template<typenameT>voidfun(Tconst&a,Tconst&b);但是你调用时却是fun(250,250.4);那你就必须写成fun<int>(250,250.4);2)需要获得特定类型的返回值,而不管参数…

大家好,又见面了,我是你们的朋友全栈君。

函数模板参数(函数参数在哪)

C++模板实参的省略

下面列举的几种情况不能省略模板实参:
1)从模板函数实参表获得的信息有矛盾之处。

template<typename T> void fun(T const& a,T const& b);但是你调用时却是fun(250,250.4);那你就必须写成fun<int>(250,250.4);
2)需要获得特定类型的返回值,而不管参数的类型如何。

template<typename T,typename RTRT fun(T const& a,T const& b);此时没有办法进行演绎,所以你可以重写template<typename RT,typename T> RT fun(T const& a,T const& b);调用时写成fun<double>(12,13);
3)虚拟类型参数没有出现在模板函数的形参表中。

用typename和class类型声明的参数称为虚拟类型参数,而用《类型修饰》声明的参数称为常规参数
4)函数模板含有常规形参。

template<typename T> void fun();调用时直接是fun()!!

 

具体template使用网上可以看到说明,在这里强调一点关于template模版实参为空的特例。 转载网络关于c++考级的要点. 知识点4:

 

    1.1  函数模板

  1.1.1  考点1:函数模板的概念和声明

    函数模板是一系列相关函数的模型或样板,这些相关函数的源代码形式相同,只是所针对的数据类型不同。对于函数模板,数据类型本身成了它的参数,因而是一种参数化类型的函数。类的成员函数也可以声明为函数模板。
    声明一个函数模板的格式如下:
    template <模板形参表声明>
    返回类型 函数名(函数形参表)
    {

       …… //函数体
    }

    其中,<模板形参表声明>是由一个或多个“模板形参”组成的,如果是多个,则要用逗号隔开。“模板形参”具有下面3种形式:

      typename 参数名
      class 参数名
     类型修饰 参数名

    这里的参数名可以是任意合法的C++标识符。前两种形式是等价的,也就是说,在声明模板形参时,关键字typename和class可以互换。用typename或class声明的参数称为虚拟类型参数;而用“类型修饰”声明的参数则称为常规参数。这里的“类型修饰”是指具体的数据类型(如int、double、char等)。函数模板的<模板形参表声明>中,一定要包含虚拟类型参数,而常规参数则可以根据实际需要选择。

    <模板形参表声明>中声明的虚拟类型参数可以用做:

     函数的返回值类型
     函数的形参的类型
     函数体内变量的类型

       例1.1.1  下列是模板声明的开始部分,其中正确的是(   )。
    A.template <T>            B.template <class T1,T2>
    C.template <class T1,class T2>     D.template <class T1;class T2>
    答案:C

       例1.1.2  下面的函数模板定义中错误的是(   )。
    A.template<class Q>       B.template<class Q>
       Q F(Q x){return Q+x;}         Q F(Q x){return x+x;}
    C.template<class T>       D.template<class T>
       T F(T x){return x*x;}         bool F(T x){return x>1;}
    解析:各个选项中声明的Q和T都是虚拟类型参数。函数模板形参表中声明的虚拟类型参数可以用做:
     函数的返回值类型
     函数的形参的类型
     函数体内变量的类型
    选项B、C和D符合以上三种用法。而选项A让虚拟类型参数Q直接参与运算是错误的。虚拟类型是具体类型(如int型,double型等)的抽象。我们知道,int本身并不能直接参与数学运算,但是由它定义的int型变量或int型参数可以直接参与运算。虚拟类型Q和T本身也不能直接参与运算,但是由它们定义的“T类型”或“Q类型”的参数x可以参与运算。所以,选项A中“Q+x”的表达是错误的。
    答案:A
1.1.2  考点2:模板函数

    函数模板中声明的函数称为模板函数。
    调用一个模板函数的格式如下:
    函数名 <模板实参表> (函数实参表);
    或
    函数名(函数实参表);
    第二种格式中省略了所有的模板实参,使用这种格式是需要一定条件的(详见考点4)。
    类模板的成员函数都是模板函数。

       例1.1.3  以下函数模板max的功能是:返回数组a中最大元素的值。请将横线处缺失部分补充完整。
    template <typename T>
    T max (T a[], int n)
    {

     T m = a[0];
     for (int i = 1; i < n; i++)
        if (a[i]>m)          ;
        return m;
    }
    解析:本题考查模板函数的定义。在编写函数体时,模板函数与普通函数是一样的。根据题意,返回的m值应该是a中最大元素的值,所以当a[i]>m时,应该将较大的a[i]值赋给m。在遍历数组a[]后,最终m就保存了数组a[]中最大元素的值。
1.1.3  考点3:函数模板的实例化

    在调用模板函数时,编译系统依据实际所使用的数据类型生成某个具体函数定义的过程称为函数模板的实例化。在实例化过程中,是用实际类型(如int、long等)替代虚拟类型的。
    实例化的过程或结果通常是看不见的,编译系统会根据函数调用的具体情况自动传递相应的模板实参,生成相应的函数实例。每一个实例就是一个函数定义。
    实例化过程中,除了可以用各种具体的C++固有数据类型取代虚拟类型,还可以用某些用户自定义类型来取代虚拟类型,这里的自定义类型包括结构体以及某些用户定义的类。

       例1.1.4  下列程序的输出结果是        。
    #include <iostream>
    using namespace std;
    template <typename T>
    T fun (T a, T b) {return (a<=b)?a:b;}
    int main()
    {

       cout<<fun(3,6)<<‘,'<<fun(3.14F,6.28F)<<endl;
       return 0;
    }
    解析:本题定义了一个模板函数fun,其形参a、b及函数返回类型均为T类型。函数fun的功能是返回a、b中数值较小的数。在main函数中,第一次调用fun时,实际上是调用了“int fun(int a,int b)”这个函数,故返回整型数据“3”。第二次调用时,实际上是调用了函数“float fun (float a, float b)”,返回浮点型数据“3.14”。
    答案:3,3.14

    1.1.4  考点4:模板实参的省略

    在调用模板函数时,编译系统需要足够的信息来判别每个虚拟类型参数所对应的实际类型,可以从两个不同的渠道获得信息:从“模板实参表”(在“<”和“>”之间)或从模板“函数实参表”(在“(”和“)”之间),“模板实参表”的信息优先于“函数实参表”的信息。如果从后者得到的信息已经能够判断其中部分或全部虚拟类型参数所对应的实际类型,而且它们又正好是“模板形参表声明”中最后的若干参数,则在“模板实参表”中可以省略这几个参数。如果所有的模板实参都被省略了,则空表“<>”也可以省略。

    但在以下情况中,模板实参是不能省略的。

    ① 从模板“函数实参表”中获得的信息有矛盾。例如,当编译系统从某一个函数实参中获得的信息是虚拟类型参数T(假设为T)对应的实际类型为int,可是从另一个函数实参中获得的信息却是虚拟类型参数T对应的实际类型为double时,就产生了矛盾。T不可能同时为
int和double型,这将导致编译器无法找到匹配的函数模板的定义,编译时报错。解决这一问题的方法之一就是显示给出虚拟类型参数T对应的模板实参,强制T对应于int或是double。
    ② 虚拟类型参数用做函数的返回值类型,而且函数需要返回特定类型的值,而不管函数实参的类型是什么。在这种情况下,需要用模板实参强制虚拟类型参数对应于特定类型。
    ③ 虚拟类型参数没有出现在模板的“函数形参表”中。此时无法从模板的“函数实参表”中获取对应的信息,因而不能省略模板实参。
    ④ 函数模板含有常规形参。常规参数是用具体的类型修饰符(如int、double、char*等)定义的,对应的实参必须是常量表达式。因此,常规参数的信息无法从模板的“函数实参表”中获得,调用模板函数时必须显示给出对应于常规参数的模板实参。

       例1.1.5  有如下函数模板定义:
    template <class T>
    T func (T x, T y){ return x*x+y*y;}
    在下列对func的调用中,错误的是(   )。
    A.func(3,5);    B.func(3.0,5.5);  C.func(3,5.5);  D.func<int>(3,5.5);
    解析:对于本题中定义的模板函数,如果用选项C中“func(3,5.5);”的形式来调用,在编译时会出现“template parameter ‘T’ is ambiguous,could be ‘double’ or ‘int’ ”的错误,也就是说T对应的实际类型是不明确的。编译系统从第一个参数“3”获得的信息是“T对应于int”,而从第二个参数“5.5”处获得的信息是“T对应于double”,二者相互矛盾,因而编译时产生错误。
    选项D中提供了模板实参<int>,因为模板实参优先于函数实参,所以T对应的实际类型是明确的,在这里就是int型。在调用过程中,double型的参数“5.5”将被自动转换成int型。
    选型A和B所提供的两个函数实参的类型是一致的,不存在矛盾。
    答案:C

       例1.1.6  有如下函数模板声明:
    template <typename T>
    T Max(T a,T b) {return (a>=b)?a:b;}
    下列对函数模板Max的调用中错误的是(   )。
    A.Max(3.5,4.5)            B.Max(3.5,4)
    C.Max<double>(3.5,4.5)      D.Max<double>(3.5,4)
    答案:B

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/129465.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Android基础教程学习(一)

    Android基础教程学习(一)1.1安装工具想要进行Android开发,必须先安装java,IDE和AndroidSDK.1.1.1Java开发包首先,需要先安装Java开发包(JDK).所有Android开发工具都需要它,在编写程序时我用的Java语言.我安装的是JDK8.建议去Oracle官网下载:JavaArchive|Oracle然后去配置环境变量JAVA_HOME,使其指向JDK安装位置.(网上教程很多)安装完成之后可以打…

  • pycharm卸载再安装_pycharm双击无法打开

    pycharm卸载再安装_pycharm双击无法打开今个发现原来下载的2017版的pycharm过期了,用一会就闪退,emmm。就想下一个新的进行迭代,结果安装好并重启了,软件就是打不开…方法一1.打开C:\Windows\System32;以管理员身份运行cmd.exe;2.在打开的cmd窗口中,输入netshwinsockreset,按回车键;3.重启电脑;博主使用这个方法后,双击后还是不行。随即用了方法二,如下:方法二只需要打开C:\Users\admin后面的admin换成你自己的当前用户名(如下图),然后把所

  • 请编写一个给list去重的函数_计算表达式

    请编写一个给list去重的函数_计算表达式c#拉姆达表达式实现List去重varlist=studentlist.OrderByDescending(a=>a.CreateDate).ToList();Console.WriteLine(JsonConvert.SerializeObject(list.Where((x,i)=>list.FindIndex(z=&gt…

  • 怎样更新pip(怎么升级python的pip)

    在Python的環境中,許多人都習慣使用PIP指令來管理模組的安裝、更新與移除的動作。但是最近我一直遇到一個問題,就是下完PIP指令執行完後都會在最後出現要求更新PIP版本的訊息,例如:WARNING:Youareusingpipversion19.2.1,howeverversion19.2.3isavailable.Youshouldconsider…

  • 公司里面常说的“BP”,“BU”到底是什么意思?

    在很多外企中,会经常说到一些专有名词,比如各BU,某BP。你知道这两个英文简写的含义吗?来看今天这些外企常用的表达吧。BU=BusinessUnit,业务单元一般公司里都会有不同的部门,如教育公司会有中小学事业部、外教事业部、大学生事业部、成人事业部等。对于多业务的集团性公司来说,每个部门都是一个BUSINESSUNIT,也就是独立完成一件事情的小组或部门。VolvoM…

  • nginx.conf文件

    nginx.conf文件

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号