摘要訊息 : C++ 17 Proposal P0305R1《Selection statements with initializer》導讀

C++ 17 Proposal P0305R1《Selection statements with initializer》導讀

C++ 有不少方式避免名稱污染, 比如名稱空間, static 函式或著 static 變數以及函式多載等等. 我們平常編寫程式的時候, 雖然可以使用這些方法去避免名稱污染, 但是通常會遇到下面一個讓人頭疼的情形 (這並不是真正的 C++ 程式碼) :

scope 0 {

    int arr[] {1, 2, 3, 4, 5};

    int value {};

    cin >> value;

    auto it {std::find(begin(arr), end(arr), value)};

    if(it == end(arr)) {

        //do something with it...

    }

}

如果物件 it 只被用在 if 陳述式中, 後面都用不到它了, 那麼我們希望 it 的作用範圍被限定在 if 陳述式中. 而實際上, 這並不可能. it 確確實實污染了 scope 0 作用範圍

而 Proposal 提出的解決方案解決了這個問題, 它提出的帶有初始化的條件陳述式允許在 if 陳述式及其 switch 陳述式中宣告變數並且初始化, 但是這個宣告並不會被轉型為布林表達式, 而真正執行判斷的是宣告之後的條件表達式 (下面的程式碼並非真正的 C++ 程式碼) :

scope 0 {

    int arr[] {1, 2, 3, 4, 5};

    int value {};

    cin >> value;

    if(auto it {std::find(begin(arr), end(arr), value)}; it == end(arr)) {

        //do something...

    }

}
enum class status {

    SUCCESSFUL, FAILED, TO_BE_CONTINUED

};

status func();

void func2(status);

scope 0 {

    switch(auto status_code {func()}; status_code) {

        case status::SUCCESSFUL :

            func2(status_code);

            break;

        case status::FAILED :

            std::terminate();

        case status::TO_BE_CONTINUED:

            std::clog << "The status is to-be-continued" << std::endl;

            break;

        default:

            break;

    }

}

通過觀察上述的程式碼, 我們發現, 變數 it 以及 status_code 的作用範圍被限定在了條件陳述式中, 而在 scope 0 作用範圍之內, 並不存在這樣的名稱. 這也算是解決了某一部分人的強迫性障礙吧

我們在之前已經介紹過, C++ 17 引入了 if constexpr. 這篇 Proposal 同樣考慮到了這個問題, 因此給 if constexpr 也提供了這樣的解決方案 :

if constexpr([init-statement; ]condition)

其中, [] 表示可選的