1. 程式人生 > >C++11系列——函式物件(Function Object)

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:

  1. takes one or more functions as arguments (i.e., procedural parameters),
  2. 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;
}

那麼問題來了,什麼時候用函式物件呢?在下面這些情況下,可以考慮使用:

  1. 函式物件是一種帶狀態的函式。函式物件可以擁有成員函式和成員變數。這意味著,函式物件擁有狀態。這在普通的函式中是不可能的。

  2. 每個函式物件有其自己的型別。普通的函式,唯有其簽名不同時,才算是型別不同。而函式物件即使簽名相同,也可以有不同的型別。我們可以將函式行為當做template引數來運用。

  3. 函式物件通常比普通函式速度快。就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};