第3章_auto佔位符(C++11~C++17)

蜗牛959發表於2024-09-01

第3章 auto佔位符(C++11~C++17)

3.1 重新定義的auto關鍵字

在C++11中靜態成員變數是可以用auto宣告並且初始化的,不過前提是auto必須使用const限定符。

static const auto x = 5;

遺憾的是,const限定符會導致x常量化,顯然這不是我們想要的結果。在C++17標準中,對於靜態成員變數,auto可以在沒有const的情況下使用。

C++20之前,無法在函式形參列表中使用auto宣告形參(注意,在C++14中,auto可以為lambda表示式宣告形參)

void fun(auto a)	// C++20之前編譯錯誤
{
    qDebug() << N;
}
int main()
{
    int x = 1;
    fun(x);
}

3.2 推導規則

1.如果auto宣告的變數是按值初始化,則推匯出的型別會忽略cv限定符;
2.使用auto宣告變數初始化時,目標物件如果是引用,則引用屬性會被忽略;
3.使用auto和萬能引用宣告變數時(見第6章),對於左值會將auto推導為引用型別;
4.使用auto宣告變數,如果目標物件是一個陣列或者函式,則auto會被推導為對應的指標型別;
5.當auto關鍵字與列表初始化組合時,這裡的規則有新老兩個版本,這裡只介紹新規則(C++17標準)。
(1)直接使用列表初始化,列表中必須為單元素,否則無法編譯,auto型別被推導為單元素的型別。
(2)用等號加列表初始化,列表中可以包含單個或者多個元素,auto型別被推導為std::initializer_list,其中T是元素型別。請注意,在列表中包含多個元素的時候,元素的型別必須相同,否則編譯器會報錯

3.3 什麼時候使用auto

簡單歸納auto的使用規則。
1.當一眼就能看出宣告變數的初始化型別的時候可以使用auto
2.對於複雜的型別,例如lambda表示式、std::bind等直接使用auto

3.4 返回型別推導【C++14】

C++14標準支援對返回型別宣告為auto的推導,例如:

 auto l = [](auto a1, auto a2) { return a1 + a2; };

3.5 lambda表示式中使用auto型別推導

在C++14標準中我們還可以把auto寫到lambda表示式的形參中,這樣就得到了一個泛型的lambda表示式

起初在後置返回型別中使用auto是不允許的,但是後來人們發現,這是唯一讓lambda表示式透過推導返回引用型別的方法了

傳入引數型別(auto& i),後置返回型別(-> auto&),接收結果的變數(auto& j)必須都是&,才能正確的返回引用。

auto lamda1 = [](auto& i) -> auto& { return i;};
auto& j = lamda1(s);

3.6 非型別模板形參佔位符【C++17】

C++17標準對auto關鍵字又一次進行了擴充套件,使它可以作為非型別模板形參的佔位符。

template<auto N>
void f()
{
    qDebug() << N;
}
int main()
{
  	f<5>();
    f<'c'>();
    f<5.6>();	// 書上說編譯錯誤  但是在Qt6.7 + MSVC2019 + C++17下透過了編譯
}

3.7 結構化繫結【C++17】

對結構體的結構化繫結(structured bindings),這是C++17標準中引入的特性。

將物件的成員繫結到變數上,從而可以更方便地訪問這些成員。

struct A {
    int a;
    double b;
};

int main() {
    auto a = A{ .a = 1, .b = 2.0 };
    auto [x, y] = a;
    qDebug() << x << " " << y; // 輸出: 1 2

    return 0;
}

相關文章