C++11系列——函式物件(Function Object)
之前總結過一篇Boost之高階函式——函式物件,介紹了幾個用於處理函式物件的 Boost C++ 庫。而目前C++11的標準庫std已經提供了函式物件的一些功能。
In mathematics and computer science, a higher-order function (also functional, functional form or functor) is a function that does at least one of the following:
- takes one or more functions as arguments (i.e., procedural parameters),
- returns a function as its result.[disputed – discuss]
All other functions are first-order functions.
一般的函式行為是:
function(arg1, arg2); // a function call
如果我們希望物件也可以有類似的功能,就必須要讓它們也有可能被呼叫
,即,通過小括號的運用和實參的傳遞,這是可能的。只需要定義operator()
,並給予合適的引數型別。
class X {
public:
return-value operator() (arguments) const ;
// ...
};
現在就可以把這個class物件
當做函式來呼叫了。
X obj;
obj(arg1, arg2); // call operator() for function object obj
// 等同於呼叫:obj.operator()(arg1, arg2);
Function Object
比較常見的例子有:
(1)map function, found in many functional programming languages, is one example of a higher-order function. It takes as arguments a function f and a list of elements, and as the result, returns a new list with f applied to each element from the list.
在C++裡,例如:
std::transform(begin, end, result, func);
(2)Sorting functions, which take a comparison function as a parameter, allowing the programmer to separate the sorting algorithm from the comparisons of the items being sorted. The C standard function qsort is an example of this.
例如:
/* qsort example */
#include <stdio.h> /* printf */
#include <stdlib.h> /* qsort */
int values[] = { 40, 10, 100, 90, 20, 25 };
int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main ()
{
int n;
qsort (values, 6, sizeof(int), compare);
for (n=0; n<6; n++)
printf ("%d ",values[n]);
return 0;
}
看下C++裡的用法。
// Generic lambdas provided by C++14.
#include <iostream>
auto twice = [](auto f, int v)
{
return f(f(v));
};
auto f = [](int i)
{
return i + 3;
};
int main()
{
std::cout << twice(f, 7) << std::endl;
}
// Or, use std::function in C++11
#include <iostream>
#include <functional>
auto twice = [](const std::function<int(int)>& f, int v)
{
return f(f(v));
};
auto f = [](int i)
{
return i + 3;
};
int main()
{
std::cout << twice(f, 7) << std::endl;
}
那麼問題來了,什麼時候用函式物件呢?在下面這些情況下,可以考慮使用:
函式物件是一種
帶狀態的
函式。函式物件可以擁有成員函式和成員變數。這意味著,函式物件擁有狀態。這在普通的函式中是不可能的。每個函式物件有其自己的型別。普通的函式,唯有其簽名不同時,才算是型別不同。而函式物件即使簽名相同,也可以有不同的型別。我們可以將函式行為當做template引數來運用。
函式物件通常比普通函式速度快。就template概念而言,由於更多細節在編譯器就已經確定,所以通常可能進行更好的優化。所以,傳入一個函式物件可能獲得更好的執行效能。
refer:
相關推薦
C++11系列——函式物件(Function Object)
之前總結過一篇Boost之高階函式——函式物件,介紹了幾個用於處理函式物件的 Boost C++ 庫。而目前C++11的標準庫std已經提供了函式物件的一些功能。 In mathematics and computer science, a high
C++之函式物件(Function Object) & for_each
函式物件 對於一些用到函式作為引數的c++STL演算法(如下面的for_each演算法函式),函式的傳遞當然可以用泛化的函式指標來進行,但是c++STL常使用的是函式物件,目的在於更簡潔、不依賴於當前
C++之函式物件/偽函式(Function Object)詳解(二)
除了自定義的函式物件,標準庫還為我們提供了一系列現成的函式物件, 比如常見的數學、邏輯運算等。例如:negate<type>(),plus<type>(),minus<type>(),multiplies<type&g
C七:指向函式的指標 ------ 函式指標(function pointer)
函式具有可賦值給指標的實體記憶體地址,一個函式的函式名就是一個指標,它指向函式的程式碼。一個函式的地址是該函式的進入點,也是呼叫函式的地址。函式的呼叫可以通過函式名,也可以通過指向函式的指標來呼叫。函式指標還允許將函式作為變元傳遞給其他函式。 不帶括號和變
c++中cmath函式庫(學生筆記)
c++中cmath是一個重要的數學函式庫。呼叫時必須包含cmath主檔案。 #include #include 其常用函式原型: int abs(int n) 求n的絕對值 double cos/sin/tan(double x) 求x的三角函式值(x為弧度值) double exp(dou
頁面物件(Page Object)模式
內容轉載自 https://www.cnblogs.com/yytesting/p/6973474.html 頁面物件(Page Object)模式是目前自動化測試領域普遍使用的設計模式之一,此模式可以大大提高測試程式碼的複用率,提高測試指令碼的編寫效率和維護效率,是中級自動化測試工程師的必備技能之一。
函式型別(Function Types):函式型別和其他型別一樣
函式型別(Function Types) 每個函式都有種特定的函式型別,由函式的引數型別和返回型別組成。 例如: 這個例子中定義了兩個簡單的數學函式:addTwoInts 和 multiplyTwoInts。這兩個函式都傳入兩個 Int型別, 返回一個合適的I
使用模擬物件(Mock Object)技術進行測試驅動開發
敏捷開發 敏捷軟體開發又稱敏捷開發,是一種從上世紀 90 年代開始引起開發人員注意的新型軟體開發方法。和傳統瀑布式開發方法對比,敏捷開發強調的是在幾周或者幾個月很短的時間週期,完成相對較小功能,並交付使用。在專案週期內不斷改善和增強。 2001 年初,在美國猶他州雪鳥滑雪勝地,17 名程式設計大師分別代表
一、函式模板(Function Template)
本系列是《C++Template》(作者:David Vandevoorde, Nicolai M. Josuttis)的學習總結。 1:函式模板(Function Template) 所謂函式模板是由引數表示的一系列的函式。函式模板可以被不同的型別引數
JavaScript中的函式過載(Function overloading)
說明 JavaScript 中沒有真正意義上的函式過載。 函式過載 函式名相同,函式的引數列表不同(包括引數個數和引數型別),根據引數的不同去執行不同的操作。 我們舉個例子看看 function overload(a){ conso
全域性物件(global object)
全域性物件(global object)在javascirpt中有著重要的用途:全域性物件的屬性是全域性定義的符號,javasciprt程式可以直接使用。當javascirpt直譯器啟動的時候(或者任何web瀏覽器載入頁面的時候),它將建立一個新的全域性物件,並給它一組定
c++11中的tuple(元組)
轉自:http://www.cnblogs.com/qicosmos/p/3318070.html 這次要講的內容是:c++11中的tuple(元組)。tuple看似簡單,其實它是簡約而不簡單,可以說它是c++11中一個既簡單又複雜的東東,關於它簡單的一面是它很容易使用,複雜的一面是它內部隱藏了太多細節,
C++11嚐鮮:Variadic Function Templates(帶變長引數的函式模板)(續)
程式碼1 #include <iostream> #include <string> #include <boost/ref.hpp> #include <b
JavaScript Function,建立函式物件(new Function()),字串當代碼來執行
demo.html:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title>
C++11系列-lambda函式
原文地址:http://towriting.com/blog/2013/08/11/lambda-closures/ C++11一個最激動人心的特性是支援建立lambda函式(有時稱為閉包)。這意味著什麼?一個Lambda函式是一個可以內聯寫在你程式碼
C++ 預定義函式物件以及函式介面卡(一)
#include<iostream> using namespace std; #include"functional" //預定義函式物件的函式實現都寫在這個庫檔案當中 #include"string" #include<vector> #in
C++11 Lambda函式(匿名函式)
C++11引入了lambda表示式,使得程式設計師可以定義匿名函式,該函式是一次性執行的,既方便了程式設計,又能防止別人的訪問。 Lambda表示式的語法通過下圖來介紹: Lambda表示
C++11系列-什麽是C++11
證明 需要 特性 泛型 枚舉 聲明 繼續 特征 線程 什麽是C++0x? C++0x是C++最新標準標準化過程中的曾用名,在這一系列文章中我們將介紹最新標準添加的一系列新的語言特性。在2011年9月份,C++0x正式由官方發布並命名C++11,現在很多編譯器已經支持了部分
C++11 Lambda表達式(匿名函數)
class 訪問 namespace 表達式 span sin clas style col http://www.cnblogs.com/RainyBear/p/5733399.html 匿名函數,好屌的樣子。 Lambda表達式的引入標誌,在‘[]’裏面可以填入‘=’
C++11 初始化列表(initializer_list)
clu amp space return ret 列表 stl容器 int stat C++11對原有的初始化列表(用花括號圍住的若幹個值)進行了大幅的擴展。以下寫法在C++11中都是被允許的: 1 int static_arr[5] = {1, 2, 3, 4};