C++ if


C語言時代,for語句引入了初始化器,代碼如下:

for(int i=0;i<100;++){
    printf("i=%d", i );
}

這是個很大的進步,i的作用域被限定在for循環內部。

但是if語句就沒有類似語法,C++98代碼要做很煩人的處理,如下:

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

int main()
{
    string a = "Hello World. C++";

    const auto it = a.find("Hello");
    if (it != string::npos)
        cout << it << " Hello\n";

    const auto it2 = a.find("World");
    if (it2 != string::npos)
        cout << it2 << " World\n";

    const auto it3 = a.find("C++");
    if (it3 != string::npos)
        cout << it3 << " C++\n";
}

這種風格的代碼見的太多了。程序員心底里最害怕的是,因為拷貝粘貼,應該寫it3的地方,被錯寫成it2或it1。

如果想用一個變量名字,這里是行不通的,因為const變量不能被再次賦值。所以我們想了個好招,代碼如下:

int main()
{
    string a = "Hello World. C++";

    {
        const auto it = a.find("Hello");
        if (it != string::npos)
            cout << it << " Hello\n"; 
    }

    {
        const auto it = a.find("World");
        if (it != string::npos)
            cout << it << " World\n";
    }

    {
        const auto it = a.find("C++");
        if (it != string::npos)
            cout << it << " C++\n";
    }
}

拷貝粘貼能愉快的進行了,不怕it名字漏改了,但是這段代碼是多么別扭,憑空出現一堆大括號呢。為此,C++17引入if的初始化:

int main()
{
    string a = "Hello World. C++";
    
    if (const auto it = a.find("Hello"); it != string::npos)
        cout << it << " Hello\n";

    if (const auto it = a.find("World"); it != string::npos)
        cout << it << " World\n";
        
    if (const auto it = a.find("C++"); it != string::npos)
        cout << it << " C++\n";

}

注意,初始化器后面是分號;結束。

int main()
{
    int i = 0;
    if ( i=1, i>0 ) {  //ok 逗號表達式
        //...
    }

    if (int i = 1, i>0) {  //error 編譯錯誤,逗號表達式中不能定義變量
        //...
    }

    if (int i = 1; i > 0) {  //ok C++17 if init
        //...
    }
}

應用例子:自動鎖

if (std::lock_guard<std::mutex> lk(mx_); v.empty()) {
    v.push_back(kInitialValue);
}

考慮對std::map的insert操作,代碼如下:

int main()
{
    map<int, string> myMap = { { 1,"hello" },{ 2, "world" } };

    auto pp = make_pair(3, "C++");

    std::pair< std::map<int,string>::iterator, bool > result = myMap.insert(pp);

    if (result.second) {
        cout << "insert ok. current position=" << result.first->first << "\n";
    }
    else {
        cout << "insert fail!" << "\n";
    }
}

result.first->first是什么鬼?代碼無比繁瑣。C++17簡化代碼如下:

int main()
{
    map<int, string> myMap = { { 1,"hello" },{ 2, "world" } };
    auto pp = make_pair(3, "C++");

    if ( const auto[iter, inserted] = myMap.insert( pp ); inserted )
        cout << "insert ok. current position=" << iter->first << "\n";
    else
        cout << "insert fail! conflict position=" << iter->first << "\n";
    }
}

inserted對應一個bool變量,iter對應一個迭代器。這樣就避免了上述pair套迭代器,迭代器解引用成另一個pair的繁瑣思路。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM