C++11 學習筆記-02.auto and decltype

auto

佔位符類型說明符 (C++11 起)

對於變量,指定要從其初始化器自動推導出其類型。

auto (1) (C++11 起)
decltype(auto) (2) (C++14 起)
類型制約 auto (3) (C++20 起)
類型制約 decltype(auto) (4) (C++20 起)

#include <iostream>
#include <utility>

using namespace  std;


int main()
{
    auto a = 1 + 2;            // a 的類型是 int
    auto c0 = a;             // c0 的類型是 int,保有 a 的副本

    auto d = {1, 2}; // OK:d 的類型是 std::initializer_list<int>
    auto n = {5};    // OK:n 的類型是 std::initializer_list<int>
    auto m{5};
    auto lambda = [](int x) { return x + 3; };

    auto (*p)() -> int; // 聲明指向返回 int 的函數的指針

}

decltype 說明符

檢查實體的聲明類型,或表達式的類

decltype ( 實體 ) (1) (C++11 起)
decltype ( 表達式 ) (2) (C++11 起)

解釋:

  • 若實參爲無括號的標識表達式或無括號的類成員訪問表達式,則 decltype 產生以此表達式命名的實體的類型。若無這種實體,或該實參指名某個重載函數,則程序非良構

  • 若實參是其他類型爲 T 的任何表達式,且
    a) 若 表達式 的值類別爲亡值,則 decltype 產生 T&&;
    b) 若 表達式 的值類別爲左值,則 decltype 產生 T&;
    c) 若 表達式 的值類別爲純右值,則 decltype 產生 T。

注意如果對象的名字帶有括號,則它被當做通常的左值表達式,從而 decltype(x) 和 decltype((x)) 通常是不同的類型。
在難以或不可能以標準寫法進行聲明的類型時,decltype 很有用,例如 lambda 相關類型或依賴於模板形參的類型。

#include <iostream>

struct A { double x; };
const A* a;

decltype(a->x) y;       // y 的類型是 double(其聲明類型)
decltype((a->x)) z = y; // z 的類型是 const double&(左值表達式)

template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) // 返回類型依賴於模板形參
{                                     // C++14 開始可以推導返回類型
    return t+u;
}

int main()
{
    int i = 33;
    decltype(i) j = i * 2;

    std::cout << "i = " << i << ", "
              << "j = " << j << '\n';

    auto f = [](int a, int b) -> int
    {
        return a * b;
    };

    decltype(f) g = f; // lambda 的類型是獨有且無名的
    i = f(2, 2);
    j = g(3, 3);

    std::cout << "i = " << i << ", "
              << "j = " << j << '\n';
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章