美文网首页
模板类型推导

模板类型推导

作者: advanced_slowly | 来源:发表于2019-05-15 19:54 被阅读0次

    理解函数模板类型推导:

    一段函数模板的伪码大概是这样的:

    template<typename   T>
     void f(ParamType   param);
    

    调用这个函数会是这样:

    f(expr);    //  用一些表达式来调用f
    

    在编译的时候,编译器通过expr来进行推导出两个类型:一个是T的,另一个是ParamType。通常来说这些类型是不同的,因为 ParamType通常包含一些类型的装饰,比 如const或引用特性。注意T的类型不仅和expr的类型独立,而且和Param的形式独立。
    下面是三个例子:
    1.Param是一个指针(包括指向const的指针)或者一个引用(包括const引用)(但并不是一个通用引用或则说万能引用)

    2.Param是一个通用引用
    附universal reference:如果一个函数的template parameter有着T&&的格式,且有一个deduce type T.或者一个对 象被生命为auto&&,那么这个parameter或者object就是一个universal reference.

    3.Param既不是指针,也不是引用

    在第一种情况和第二种情况下,T和param类型推到中,调用函数的实参的const特性将给予保留。
    1.第一种情况:

    当Param是一个指针或者非通用的引用:在这种情况下类型推导的过程如下
    -1. 如果 expr 的类型是个引用,忽略引用的部分。
    -2. 然后利用 expr 的类型和 ParamType 对比去判断 T 的类型。

    # include <iostream>
    
    template <typename T>
    void f(T& param)
    {
        //param = 270;      //作为测试,这里假设param的数据类型支持赋值
        std::cout << param << std::endl;
    }
    int main()
    {
        int x = 27;         //x是一个int
        const int y = x;    //y是一个const int
        const int& z = y;   //z是一个const int的引用
    
        //f(x);             //T是int,Param是int &
        //f(y);             //T是const int,Param是const int &
        f(z);               //T是const int,Param是const int &
    
        return 0;
    }
    

    2.第二种情况:

    当Param是一个通用引用:如果expr是一个左值,那么T和Param都将被推导为左值引用。如果是右值,那么就遵循普通法则

    # include <iostream>
    
    template <typename T>
    void f(T&& param)
    {
        std::cout << param << std::endl;
    }
    int main()
    {
    
        int x = 27;         //x是一个int
        const int y = x;    //y是一个const int
        const int& z = y;   //z是一个const int的引用
    
        f(x);               //T是一个int &,param是一个int &
        f(y);               //T是一个const int &,param是一个const int &
        f(z);               //T是一个const int &,param是一个const int &
        f(100);             //T是一个int,Param是一个int &&
    
        return 0;
    }
    

    3.第三种情况:

    当Param既不是指针也不是一个引用:在这种情况下由于param既不是一个指针也不是一个引用,调用函数传递给形参param的是一个实参的副本。因此调用函数的实参的const特性将不被保留。其推导法则为:

    -1.和之前一样,如果expr的类型是个引用,将会忽略引用的部分。
    -2.如果在忽略 expr 的引用特性,expr是个const的,也要忽略掉 const。如果 是volatile,照样也要忽略掉(volatile对象并不常见)。

    # include <iostream>
    
    template <typename T>
    void f(T param)
    {
        param = 270;
        std::cout << param << std::endl;
    }
    
    int main()
    {
        int x = 27;         //x是一个int
        const int y = x;    //y是一个const int
        const int& z = y;   //z是一个const int的引用
    
        f(x);               //T是一个int,Param是一个int 
        f(y);               //T是一个int,Param是一个int
        f(z);               //T是一个int,Param是一个int
        return 0;
    }
    

    理解auto模板类型推导

    除了一个例外,auto模板类型推导就是函数模板类型推导。当一个变量被声明为auto,auto相当于模板中的T,而对变量做的相关的类型限定就像ParamType。这个例外是当使用c++11的语法使用花括号来初始化auto变量时:

    auto a = {100};//此时a的类型被推导为std::intializer_list<int>
    

    相关文章

      网友评论

          本文标题:模板类型推导

          本文链接:https://www.haomeiwen.com/subject/efapaqtx.html