1. 程式人生 > 其它 >在程式中使用STL(第7章)(條款43)

在程式中使用STL(第7章)(條款43)

技術標籤:《Effective STL》讀書筆記c++

條款43:演算法呼叫優先於手寫的迴圈

有三個理由

效率:演算法通常比程式設計師自己寫的迴圈效率更高;

正確性:自己寫迴圈比使用演算法更容易出錯;

可維護性:使用演算法的程式碼通常比手寫迴圈的程式碼更加簡潔明瞭;

書中的例子

   void dequeTest() {
        deque<int> dq{2, 3, 4};
        dq.push_back(5);
        dq.push_front(1);
        auto idq = dq.insert(dq.cbegin(), 0); // 注意,插入後返回插入節點的迭代器
        idq = dq.insert(dq.cend(), 6); // 注意,插入後返回插入節點的迭代器

        int arr[]{11, 12, 13, 14, 15}; // 測試用資料
        const int N = 5;

        // 不使用演算法的例子,需要訊息維護迭代器的有效性
        auto initer = dq.begin();
        for (int i = 0; i < N; ++i) {
            initer = dq.insert(initer, arr[i] + 10);
            ++initer;
        }

        // 使用演算法的例子
        // 1)將陣列依次插入到deque後面
        std::copy(arr, arr + N, std::back_inserter(dq));
        // 2)將陣列按照原來的順序依次+10後插入deque前面,採用lambda表示式實現
        std::transform(std::begin(arr), std::end(arr), std::inserter(dq, dq.begin()),
                       [](int x) { return x + 10; });  // lamada表示式
        // 3)將陣列按照原來的順序依次+10後插入deque前面,採用bind 標準函式物件實現
        std::transform(std::begin(arr), std::end(arr), std::inserter(dq, dq.begin()),
                       std::bind(std::plus<int>(), std::placeholders::_1, 10));  // bind標準函式物件

        return;
    }

輸出:

書中還舉了個例子,有些場景下使用迴圈更清晰,不過作者出版樹的時候C++11還沒有面世,因此那個例子是合理的,現在有lambda,書中那個例子也可以用演算法優雅的完成,程式碼如下

  void dequeTest() {
        // 想要表明在一次迭代中完成什麼工作,則使用迴圈比演算法更為清晰
        std::vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9};
        int lowbound = 4;
        int upperbound = 6;
        auto iter = vec.begin();
        for (; iter != vec.end(); ++iter) {
            if (*iter > lowbound && *iter < upperbound) {
                break;  // *iter == 5
            }
        }

        // 然而新版的C++也不是如此了,以前做法確實比較麻煩,還需要寫個函式物件,或者採用其他方式,現在有lambda
        auto i = std::find_if(vec.begin(), vec.end(), [=](int e) { return e > lowbound && e < upperbound; });

        return;
    }