首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

STL bind2nd、for_each 與 transform 正確用法詳解

     編輯:關於C++

常見錯誤嘗試


void print(int& a, const int b) { a += b; }

int main() {
    list my_list;
    // ...
    for_each(my_list.begin(), my_list.end(), bind2nd(print, 3)); // 編譯失敗
}

錯誤原因分析

  1. bind2nd 需要仿函數,而非普通函數:bind2nd 接受繼承自 binary_function 的仿函數物件。
  2. for_each 不允許修改元素:標準規定 UnaryFunction 不得透過參數執行非常數操作。

正確做法:自訂仿函數 + transform


#include 
#include 
#include 
#include 
#include 

using namespace std;

// 繼承 binary_function:第一參數、第二參數、回傳型別
struct AddPrint : public binary_function {
    int operator()(int a, int b) const {
        cout << a + b << endl;
        return a + b; // transform 需要回傳值
    }
};

int main() {
    vector my = {0, 1, 2};

    // 1. 原始內容
    copy(my.begin(), my.end(), ostream_iterator(cout, " "));
    cout << "\n-----\n";

    // 2. for_each 僅輸出,不修改容器
    for_each(my.begin(), my.end(), bind2nd(AddPrint(), 3));
    cout << "\n-----\n";
    copy(my.begin(), my.end(), ostream_iterator(cout, " "));
    cout << "\n-----\n";

    // 3. transform 真正修改元素
    transform(my.begin(), my.end(), my.begin(), bind2nd(AddPrint(), 3));
    cout << "\n-----\n";
    copy(my.begin(), my.end(), ostream_iterator(cout, " "));
    cout << endl;

    return 0;
}

輸出結果

0 1 2
-----
3
4
5
-----
0 1 2
-----
3
4
5
-----
3 4 5

關鍵點總結

算法用途是否修改容器仿函數需求
for_each遍歷副作用 (列印、記錄)否 (標準禁止)unary_function 或可呼叫物件
transform元素轉換並寫回是unary_function 或 binary_function (搭配 bind2nd)

現代 C++ (C++11+) 寫法


// Lambda 取代 bind2nd + 仿函數結構
transform(v.begin(), v.end(), v.begin(), [](int x){ return x + 3; });
for_each(v.begin(), v.end(), [](int x){ cout << x << ' '; });

// 範圍-based for (C++11)
for (auto& x : v) x += 3;

避坑指南

  • bind2nd / bind1st 已在 C++11 棄用,C++17 移除,請改用 std::bind 或 Lambda。
  • for_each 回傳傳入的仿函數副本 (C++11 前) 或引用 (C++11 起),可用於累積狀態。
  • 若需修改容器元素,務必使用 transform 或直接迴圈。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved