• modern effective C++ -- Deducint Types


    1. 理解模板类型推导

    1. expr是T&

    template<typename T>
    void f(T & param);
    // 我们声明如下变量
    int x = 27;
    const int cx = x;
    const int& rx = x;
    

    函数调用时,推导出的Param和T的类型如下:

    f(x);  // T is int, param's type is int&
    f(cx); // T is const int, param's type is const int&
    f(rx); // T is const int, param's type is const int&
    

    需要特别注明的是,通过T&的方式传入数组,数组的大小信息不会丢失。

    template<typename T>
    void f(T& param);
    int arr[10];
    f(arr); // T is const int[10], param type is const int(&)[10]
    

    在类型推导期间,数组和函数将退化为指针类型,除非他们是被初始化为引用。

    2. expr是const T&

    template<typename T>
    void f(const T& param);
    
    int x = 27;
    const int cx = x;
    const int& rx = x;
    

    在进行类型推导的时候,rx的引用性被忽略了。

    f(x);  // T is int, param's type is const int&
    f(cx); // T is int, param's type is const int&
    f(rx); // T is int, param's type is const int&
    

    3. param是一个指针类型

    template<typename T>
    void f(T* param); // param is now a pointer
    
    int x = 27;
    const int* px = &x;
    f(&x); // T is int, param's type is int *
    f(px); // T is const int, param's type is const int *
    

    4. param是universial reference

    template<typename T>
    void f(T&& param); // param is now a universal reference
    
    int x = 27;
    const int cx = x;
    const int rx = x;
    
    f(x);  // x is lvalue, so T is int&, param's type is also int&
    f(cx); // cx is lvalue, so T is const int&, param's type is also const int&
    f(rx); // rx is lvalue, so T is const int&, param's type is also const int&
    f(27); // 27 is rvalue, so T is int, param's typs is int&&
    

    5. param 既不是指针也不是引用

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

    当ParamType既不是指针也不是引用的时候,我们按照值传递的方式进行处理。
    需要举出一个有用的例子:

    template<typename T>
    void f(T param);
    const char* const ptr = "hello world
    ";
    f(ptr); // param's type is const char* 
    

    2. 理解auto自动类型推导

    auto 类型对象推导通常和模板类型推导是相同的。
    例子:

    const char name[] = "zhouyang";
    auto arr1 = name; // arr1's type is const char*
    auto& arr2 = name; // arr2's type is const char(&)[9]
    void someFunc(int, double); // someFunc is a function
    auto func1 = someFunc; // func1's type is void(*)(int, double)
    auto& func2 = someFunc; // func2's type is void(&)(int, double)
    

    唯一的例外是:使用auto和大括号进行初始化时,自动推导为std::initializer_list。并且,对于使用括号进行的初始化,模板类型推导会失败。

    3. 理解decltype

    decltype 一般情况下总是返回变量名或者表达式的类型而不做任何的修改。

    const int i = 0; // decltype(i) is const int
    bool f(const Widget& w) // decltype(w) is const Widget&
    Widget W; // decltype(w) is Widget
    

    在C++14中,提供了decltype(auto)的支持,它从初始化式子中推导类型,使用的是decltype的推导规则。

    Widget w;
    cosnt Widget& cw = w;
    auto myWidget1 = cw; // myWidget1's type is Widget
    decltype(auto) myWidget2 = cw; // decltype type deduction:
                                   // myWidget2's type is const Widget&
    // 注:可以在模板中使用
    

    特例:

    #include <iostream>
    using namespace std;
    
    int main()
    {
      int temp = 10;
    
      decltype((temp)) temp1 = temp; // temp1's type is int& 
      temp1 = 1;
      cout<< temp << endl;
      
      return 0;
    }
    //输出 : 1
    

    4. 了解如何查看推导出的类型

    可以利用编译器诊断来完成。我们想要知道被推导出的类型,可以首先声明一个类模板,但是不定义它。那么编译器的出错信息会包含推导的类型信息。

    template<typename T>
    class TD;
    

    通过编译器内置的宏定义,可以输出函数类型

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    void test_func(int)
    {
    #if defined(__GNUC__)
      cout << __PRETTY_FUNCTION__ << endl;
    #elif defined(_MSC_VER)
      cout << __FUNCSIG__ << endl;
    #endif
    }
    
    int main()
    {
      test_func(10);
    
      return 0;
    }
    
  • 相关阅读:
    LeetCode449. 序列化和反序列化二叉搜索树
    LeetCode448. 找到所有数组中消失的数字
    一行代码如何隐藏 Linux 进程?
    C语言这么厉害,它自身又是用什么语言写的?
    了解C语言,是否代表了解C ++的一半?
    C语言小白那些不知道的事儿
    6 条 Git 实用技巧
    干货来袭,收藏方便找到该网站
    零基础小白如何入门Shell,快来看看(收藏)这篇大总结!!
    Java用于嵌入式系统的优点和局限
  • 原文地址:https://www.cnblogs.com/zhoudayang/p/6935256.html
Copyright © 2020-2023  润新知