C++ 中將函數作為參數傳遞
1. 通過指針傳遞函數
函數可以通過傳遞函數的地址來作為參數傳遞;簡而言之,就是通過指針實現這一點。
示例代碼
#include <iostream>
using namespace std;// 定義加法和減法函數
#include <iostream>
#include <string>
using namespace std;// 定義拼接字符串的函數
string concatenate(const string& str1, const string& str2) {return str1 + str2;
}// 定義轉換成大寫字母的函數
string to_uppercase(const string& str) {string result = str;for (auto& ch : result) {ch = toupper(ch);}return result;
}// 函數接受指向函數的指針作為參數
string invoke(const string& str1, const string& str2, string (*f)(const string&, const string&)) {return f(str1, str2);
}int main() {string str1 = "Hello, ";string str2 = "World!";// 將 concatenate 函數的指針作為參數傳遞cout << "Concatenated String: ";cout << invoke(str1, str2, &concatenate) << '\n'; // 輸出拼接的字符串// 將 to_uppercase 函數的指針作為參數傳遞cout << "Uppercase String: ";cout << invoke(str1, str2, &to_uppercase) << '\n'; // 輸出轉換成大寫的字符串return 0;
}
輸出:
Concatenated String: Hello, World!
Uppercase String: HELLO, WORLD!
說明:
在這個例子中,concatenate 和 to_uppercase 函數通過指針傳遞給 invoke 函數。
2. 使用 function<>
包裝器
在 C++11 中,std::function
類模板可以將函數作為對象傳遞,使得將函數作為參數變得更加靈活。
示例代碼
#include <bits/stdc++.h>
using namespace std;// 定義比較函數
bool greater_than(int x, int y) { return x > y; } // 大于比較
bool less_than(int x, int y) { return x < y; } // 小于比較// 函數接受 std::function 對象作為參數
bool invoke(int x, int y, function<bool(int, int)> f) {return f(x, y);
}int main() {int a = 20, b = 10;// 傳遞比較函數作為 std::function 對象cout << "Is " << a << " greater than " << b << "? ";cout << (invoke(a, b, &greater_than) ? "Yes" : "No") << '\n'; // 輸出大于比較結果cout << "Is " << a << " less than " << b << "? ";cout << (invoke(a, b, &less_than) ? "Yes" : "No") << '\n'; // 輸出小于比較結果return 0;
}
輸出:
Is 20 greater than 10? Yes
Is 20 less than 10? No
說明:
-
在這個例子中,greater_than 和 less_than 函數通過 std::function 被傳遞給 invoke 函數,以進行數字比較。
-
std::function<bool(int, int)> 是一個可以接收任何具有相同簽名(bool(int, int))的函數對象的容器。
3. 使用 Lambda 表達式
Lambda 表達式是 C++ 提供的一種內聯函數的簡潔方式,可以在需要函數作為參數的地方直接定義匿名函數。
示例代碼
#include <functional>
#include <iostream>
using namespace std;// 函數接受 std::function 對象作為參數
int invoke(int x, int y, function<int(int, int)> func) {return func(x, y);
}// 主函數
int main() {// 使用 Lambda 表達式進行加法操作cout << "Addition: ";int k = invoke(20, 10, [](int x, int y) -> int { return x + y; });cout << k << '\n'; // 輸出加法結果// 使用 Lambda 表達式進行減法操作cout << "Subtraction: ";int l = invoke(20, 10, [](int x, int y) -> int { return x - y; });cout << l << '\n'; // 輸出減法結果return 0;
}
輸出:
Addition: 30
Subtraction: 10
說明:
- Lambda 表達式提供了一種非常簡潔的方式來定義函數對象。在
invoke
函數中,我們直接將一個 Lambda 表達式傳遞給std::function
對象。 - Lambda 的好處是它不需要顯式的函數聲明,可以直接在調用的地方定義。
4. 傳遞類的成員函數
如果需要傳遞類的成員函數作為參數,非靜態成員函數的傳遞會稍微復雜一些,因為成員函數需要綁定到對象上。
示例代碼
#include <bits/stdc++.h>
using namespace std;class C {
public:int multiply(int a, int b) {return a * b; // 成員函數,計算乘積}
};void invoke(function<int(int, int)> calc) {// 調用成員函數cout << "Product: " << calc(10, 20) << '\n';
}int main() {C c; // 創建對象 c// 使用 bind 綁定成員函數auto calc = bind(&C::multiply, &c, placeholders::_1, placeholders::_2);// 傳遞綁定的成員函數invoke(calc);return 0;
}
輸出:
Product: 200
說明:
- 在
main
函數中,使用bind
將成員函數C::multiply
與對象c
綁定。 bind
返回一個可以作為普通函數調用的對象,我們將其傳遞給invoke
函數。