C++ 仿函式
阿新 • • 發佈:2020-11-12
一. 仿函式(Functor)
仿函式(functor)又稱為函式物件(function object)是一個能行使函式功能的類。仿函式的語法幾乎和我們普通的函式呼叫一樣,不過作為仿函式的類,都必須過載operator()運算子,舉個例子:
1 class Func{ 2 public: 3 void operator() (const string& str) const { 4 cout<<str<<endl; 5 } 6 };
用仿函式實現迭代增量:
1 // C++ program to demonstrate working of2 // functors. 3 #include <bits/stdc++.h> 4 using namespace std; 5 6 // A Functor 7 class increment 8 { 9 private: 10 int num; 11 public: 12 increment(int n) : num(n) { } 13 14 // This operator overloading enables calling 15 // operator function () on objects of increment16 int operator () (int arr_num) const { 17 return num + arr_num; 18 } 19 }; 20 21 // Driver code 22 int main() 23 { 24 int arr[] = {1, 2, 3, 4, 5}; 25 int n = sizeof(arr)/sizeof(arr[0]); 26 int to_add = 5; 27 28 transform(arr, arr+n, arr, increment(to_add));29 30 for (int i=0; i<n; i++) 31 cout << arr[i] << " "; 32 }
其中,std::transform :
std::transform在指定的範圍內應用於給定的操作,並將結果儲存在指定的另一個範圍內:
1 template<class InputIt, class OutputIt, class UnaryOperation> 2 OutputIt transform(InputIt first1, InputIt last1, OutputIt d_first, 3 UnaryOperation unary_op) 4 { 5 while (first1 != last1) { 6 *d_first++ = unary_op(*first1++); 7 } 8 return d_first; 9 } 10 11 template<class InputIt1, class InputIt2, 12 class OutputIt, class BinaryOperation> 13 OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2, 14 OutputIt d_first, BinaryOperation binary_op) 15 { 16 while (first1 != last1) { 17 *d_first++ = binary_op(*first1++, *first2++); 18 } 19 return d_first; 20 }
二. STL中的典型仿函式
std::less ,std::equal_to和 std::greater 可用於比較,典型使用示例:
1 // greater example 2 #include <iostream> // std::cout 3 #include <functional> // std::greater 4 #include <algorithm> // std::sort 5 6 int main () { 7 int numbers[]={20,40,50,10,30}; 8 std::sort (numbers, numbers+5, std::greater<int>()); 9 for (int i=0; i<5; i++) 10 std::cout << numbers[i] << ' '; 11 std::cout << '\n'; 12 return 0; 13 }
三. std::bind1st和std::bind2nd
std::bind1st和std::bind2nd函式用於將一個二元運算元轉換成一元運算元。
示例:
1 #include <iostream> 2 #include <iomanip> 3 #include <algorithm> 4 #include <functional> 5 #include <cmath> 6 #include <cstddef> 7 #include <vector> 8 9 int main() 10 { 11 std::vector<double> a = {0, 30, 45, 60, 90, 180}; 12 std::vector<double> r(a.size()); 13 const double pi = std::acos(-1); // since C++20 use std::numbers::pi 14 15 std::transform(a.begin(), a.end(), r.begin(), 16 std::bind1st(std::multiplies<double>(), pi / 180.)); 17 // an equivalent lambda is: [pi](double a){ return a*pi / 180.; }); 18 19 for(std::size_t n = 0; n < a.size(); ++n) 20 std::cout << std::setw(3) << a[n] << "° = " << std::fixed << r[n] 21 << " rad\n" << std::defaultfloat; 22 }