天天看點

C++11:類型推導

auto

auto的自動類型推導,用于從初始化表達式中推斷出變量的資料類型。從這個意義上講,auto并非一種“類型”聲明,而是一個類型聲明時的“占位符”,編譯器在編譯時期會将auto替換為變量實際的類型。

通過auto的自動類型推導,可以大大簡化我們的程式設計工作:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

double foo() {}

void func(vector<string> & tmp)
{
    for (auto i = tmp.begin(); i < tmp.end(); i++)
    {
        // 一些代碼
    }
}

int main()
{
    auto x = 1;      // x的類型為int
    auto y = foo();  // y的類型為double
    struct m { int i; }str;
    auto str1 = str;    // str1的類型是struct m

    auto z;     // err, 無法推導,無法通過編譯
    z = x;

    return 0;
}      

注意點:

void fun(auto x =1) {}  // 1: auto函數參數,有些編譯器無法通過編譯

struct str
{
    auto var = 10;   // 2: auto非靜态成員變量,無法通過編譯
};

int main()
{
    char x[3];
    auto y = x;
    auto z[3] = x; // 3: auto數組,無法通過編譯

    // 4: auto模闆參數(執行個體化時),無法通過編譯
    vector<auto> x = {1};

    return 0;
}      

decltype

#include <typeinfo>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int i;
    decltype(i) j = 0;
    cout << typeid(j).name() << endl;   // 列印出"i", g++表示integer

    float a;
    double b;
    decltype(a + b) c;
    cout << typeid(c).name() << endl;   // 列印出"d", g++表示double

    vector<int> vec;
    typedef decltype(vec.begin()) vectype; // decltype(vec.begin()) 改名為 vectype

    vectype k;  // 這是auto無法做到的
    //decltype(vec.begin()) k;  // 這是auto無法做到的
    for (k = vec.begin(); k < vec.end(); k++)
    {
        // 做一些事情
    }

    enum {Ok, Error, Warning}flag;   // 匿名的枚舉變量
    decltype(flag) tmp = Ok;

    return 0;
}      

追蹤傳回類型

int func(int, int);
auto func2(int, int) -> int;

template<typename T1, typename T2>
auto sum(const T1 & t1, const T2 & t2) -> decltype(t1 + t2)
{
    return t1 + t2;
}

template <typename T1, typename T2>
auto mul(const T1 & t1, const T2 & t2) -> decltype(t1 * t2)
{
    return t1 * t2;
}

int main()
{
    auto a = 3;
    auto b = 4L;
    auto pi = 3.14;

    auto c = mul( sum(a, b), pi );
    cout << c << endl;  // 21.98

    return 0;
}