泛型 lambda 表達式
因 Lambda expression 帶來的諸多好處,大家開始寫諸多臨時小函數(可以不用命名!哈), 但有時候只是參數型別,不同其實邏輯大同小異,但卻要再寫一個 Lambda expression,看起來有點不夠乾淨。 ex : 看以下兩個例子吧, 只是兩數相加,差別只在於一個是 int, 另一個是 double 型別。
1
2
3
auto lambda = [](int a, int b) {
return a + b;
};
1
2
3
auto lambda = [](double a, double b) {
return a + b;
};
這種問題,在 C++14 裡可以解決 !
在 C++14 中,泛型 Lambda 表達式(generic lambda expressions)引入了一個強大的特性,使得 Lambda 表達式可以接收任意類型的參數,而無需預先指定參數類型。這一特性使得 Lambda 表達式在使用模板化和泛型編程時變得更加靈活。
1 基本泛型 Lambda 表達式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
int main() {
auto add = [](auto a, auto b) {
return a + b;
};
std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
std::cout << "add(1.5, 2.5) = " << add(1.5, 2.5) << std::endl;
std::cout << "add(std::string(\"Hi \"), \"Kobe\") = " << add(std::string("Hi "), "Kobe") << std::endl;
return 0;
}
執行結果如下,不管哪個型別的資料,只要 operator+ 有定義,就可以帶入。
2 在 STL 算法中使用泛型 Lambda 表達式
簡單一句話,更好寫。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> numbers = { 101, 102, 103, 104, 105 };
std::for_each(numbers.begin(), numbers.end(), [](auto n) {
std::cout << n << " ";
});
std::cout << std::endl;
std::transform(numbers.begin(), numbers.end(), numbers.begin(), [](auto n) {
return n * 2;
});
std::for_each(numbers.begin(), numbers.end(), [](auto n) {
std::cout << n << " ";
});
std::cout << std::endl;
return 0;
}
使用時機
- 處理異構數據:當需要處理不同類型的數據時,泛型 Lambda 表達式可以避免重複定義多個重載函數。
- 模板化算法:在使用 STL 算法時,泛型 Lambda 表達式可以增強代碼的靈活性和可重用性。
- 簡化代碼:在進行泛型編程時,使用泛型 Lambda 表達式可以使代碼更加簡潔和易讀,避免了不必要的模板代碼。
泛型 lambda 表達式可以取代 template !?
Lambda 表達式 vs 模板 臨時小函數:Lambda 表達式更適合用於簡單的臨時函數,特別是在算法和回調函數中。 複雜泛型邏輯:模板更適合於需要處理複雜泛型邏輯和類型推斷的情況,如泛型容器、算法和類。 可讀性和簡潔性:Lambda 表達式在代碼簡潔性和可讀性方面通常優於模板,但當邏輯變得複雜時,模板可能提供更清晰的結構。
1
2
3
4
5
6
7
8
template<typename T>
void printVector(const std::vector<T>& vec) {
for (const T& elem : vec) {
std::cout << elem << " ";
}
std::cout << std::endl;
}
在這個示例中,模板函數 printVector 可以處理不同類型的 std::vector,展示了模板在處理不同類型的通用性和強大能力。
結論, No !!!


