zoukankan      html  css  js  c++  java
  • 条款1:理解模板类型推导

    条款1:理解模板类型推导

    模板及调用的一般形式:

    template<typename T>
    void f(ParamType param);
    
    f(expr);        //从expr来推导T和ParamType的类型
    

    情况1:ParamType是个指针或引用,但不是个万能引用

    推导规则:

    1.若expr具有引用类型,先将引用部分忽略。

    2.尔后,对expr的类型和ParamType的类型进行模式匹配,来决定T的类型。

    例如,有如下的模式:

    template<typename T>
    void f(T& param);       //param是个引用
    
    又声明了下列变量:
    
    int x = 27;         //x:int
    const int cx = x;   //cx:const int
    const int& rx = x;  //rx:const int &
    
    在各次调用中,对param和T的类型推导如下:
    
    f(x);   //T:int, param:int&
    f(cx);  //T:const int, param:const int&
    f(rx);  //T:const int, param:const int&
    

    在第二个和第三个调用语句中,由于cx和rx的值都被指明为const,所以T的类型被推导为const int,从而形参param的类型就成了const int&。

    上述调用语句示例演示的都是左值引用形参,但是右值引用形参的类型推导方式是完全相同的。

    若将形参类型从T&改为const T&,结果和意想中的差别不大。cx和rx的常量性仍得到满足,但由于现在假定param具有const引用类型,T的类型推导结果中没有必要再包含const了。推导如下:

    template<typename T>
    void f(const T& param);       //param现在是个const引用
    
    int x = 27;         //同前
    const int cx = x;   //同前
    const int& rx = x;  //同前
    
    f(x);   //T:int, param:const int&
    f(cx);  //T:int, param:const int&
    f(rx);  //T:int, param:const int&
    

    若param是个指针(或指向const对象的指针)时,推导方式本质上一样:

    template<typename T>
    void f(T* param);       //param现在是个指针
    
    int x = 27;         //同前
    const int *px = &x; //px:const int
    
    f(&x);   //T:int, param:int*
    f(px);  //T:const int, param:const int*
    
    

    情况2:ParamType是个万能引用

    • 若expr是个左值,T和ParamType都会被推导为左值引用。这个结果有两重神奇之处:首先,这是在模板类型推导中,T被推导为引用类型的唯一情形。其次,尽管在声明时使用的是右值引用语法(T&&),它的型别推导确实左值引用。

    • 若expr是个右值,则应用“常规”(情形1中的)规则。

    例如:

    template<typename T>
    void f(T&& param)       //param现在是个万能引用
    
    int x = 27;             //同前
    const int cx = x;       //同前
    const int& rx = x;      //同前
    
    f(x);       //x是左值,所以T的类型是int&,param也是
    f(cx);      //cx是左值,所以T是const int&,param也是
    f(rx);      //rx是左值,所以T是const int&,param也是
    f(27);      //27是右值,所以T是int,这样一来,param:int&&
    
    #### 情况3:ParamType既非指针也非引用(即按值传递)
    
    ```cpp
    template<typename T>
    void f(T param)         //现在是按值传递
    

    这意味着无论传入什么,param都会是它的一个副本,即一个全新的对象。这也决定了此时的推导规则:

    • 一如之前,若expr具有引用类型,则忽略引用属性。
    • 忽略expr的引用性之后,若expr是const或者volatile对象,也忽略之。
    int x = 27;             //同前
    const int cx = x;       //同前
    const int& rx = x;      //同前
    
    f(x);       //T和param:int
    f(cx);      //T和param:int
    f(rx);      //T和param:int
    

    也即实参的&,cv属性影响不了形参param

    新战场:https://blog.csdn.net/Stephen___Qin
  • 相关阅读:
    数据库中的 索引
    JQuery中ajax请求
    如何优化广告,提高点击率
    常用的正则表达式
    全栈工程师之路中级篇之小程序开发前言
    ionic入门教程第四课使用$controllerProvider按需加载controller
    全栈工程师之路中级篇之小程序开发第一章第一节注册小程序
    ionic入门教程第三课在项目中使用requirejs分离controller文件和server文件
    ionic入门教程第五课举例子说明异步回调$q及$q在项目中的用法
    求两个整数的最大公约数和最小公倍数
  • 原文地址:https://www.cnblogs.com/Stephen-Qin/p/9120654.html
Copyright © 2011-2022 走看看