STL中的函式物件

2021-07-07 07:37:55 字數 2281 閱讀 7672

stl不但使我們能夠更輕鬆、更快捷地編寫複雜的**,而且使編寫的**既標準又高度優化。

std::vectornames;

// ...

std::sort(names.begin(), names.end());

stl另乙個優雅之處在於高度可配置。在以上的**中,使用string的小於(<)操作符對vector中的string元素進行排序,但在其它場合,未必總有乙個小於操作符可供使用,而且有時並不希望以公升序方式進行排序。

class state

;state類用於表示聯邦的乙個州,它沒有小於操作符,而且也不打算為它實現乙個,因為「乙個州小於另乙個州」說不清是什麼意思。幸運的是,對於這樣的情形來說,stl一般允許我們指定乙個替代的類似小於操作符(less-than-like)的操作。這樣的操作被稱為「比較器」,因為它用於比較兩個值:

inline bool popless(const state& a, const state& b)

擁有針對state的比較器之後,就可以用它進行排序了:

state aunion[50];

// ...

std::sort(aunion, aunion + 50, popless); // 按人口數進行排序

這裡我們傳遞乙個指向popless函式的指標作為比較器(函式名字會退化成乙個指標)。因為popless作為函式指標進行傳遞,所以它在sort內無法被內聯。如果希望得到快速的排序操作,這種做法只能讓人感到遺憾了。

如果使用函式物件作為比較器,情況就會好很多:

struct popless : public std::binary_function

};popless型別是乙個典型的、有著正確構造的stl函式物件的例子。

首先,它是乙個函式物件。它過載了函式呼叫操作符,因此可以以普通函式呼叫的語法呼叫。這一點很重要,因為諸如sort這樣的stl泛型演算法是以這種方式編寫的:函式指標和函式物件都可以用來例項化它們,只要此二者可以採用典型的函式呼叫語法進行呼叫即可。乙個具有過載的operator()的函式物件完全可以滿足這個語法要求。

其次,它派生於標準的binary_function基類。此項機制允許其它部分的stl實現詢問函式物件編譯器問題。在這個例子中,從binary_function派生下來的popless型別允許我們找出函式物件的引數和返回值型別。不過在這裡我們並沒有利用這種能力,但是可以打賭肯定有人需要這樣的能力,而且希望我們的popless型別可以為其他人所用。

第三,這個函式物件沒有資料成員、沒有虛函式、沒有顯示宣告的建構函式和析構函式,且對operator()的實現是內聯的。用作stl比較器的函式物件一般都很小巧。簡單且快速。當然可以設計乙個具有重型實現的stl函式物件,但這種做法通常不是明智之舉。當與stl協同使用時,在函式物件中避免(或盡量少)使用資料成員的另乙個原因在於,stl實現可能為會乙個函式物件產生若干份複製,而且假定所有這些複製都是一致的。為了確保乙個物件的所有複製一致,最簡單的方式就是不要讓物件帶有任何資料成員。

現在我們就可以使用該函式物件對這個aunion進行排序:

std::sort(aunion, aunion + 50, popless());   // 按人口數進行排序

請注意在這個sort呼叫中跟在popless後面的圓括號。popless是乙個型別,但是我們必須傳入乙個該型別的物件作為函式的引數。通過在popless型別名字後面附加一對圓括號,就建立了乙個沒名字的臨時popless物件,此物件僅存活於函式呼叫期間(這個沒名字的物件即總所周知的「匿名臨時物件」)。也可以宣告並傳入乙個具名物件:

popless comp;

std::sort(aunion, aunion + 50, comp); // 按人口數進行排序

然而,傳入乙個匿名臨時物件更簡單、更符合習慣,而且擊鍵次數更少。

使用函式物件作為比較器還有乙個額外的好處,就是比較操作將被內聯處理,而使用函式指標則不允許內聯。原因在於,當乙個sort函式模板例項化時,編譯器知道比較器的型別是popless,從而使它知道popless:operator()將被呼叫,接著使它可以內聯該函式。

在stl中,函式物件另乙個常見的用途是用作判斷式。判斷式是乙個詢問關於單個物件的真/假問題的操作(可以將比較器視作一種二元判斷式)。

struct iswarm : public std::unary_function

};stl判斷式的設計知道方針與stl比較器的一致,唯一的例外在於,前者是一元函式,而非二元函式。從我們前面排過序的state結果開始,採用乙個適當的判斷式,可以讓我們很容易就能找到乙個氣候溫暖且人數較少的州:

state* warmandsparse = find_if(aunion, aunion + 50, iswarm());

STL中的函式物件 一

為使類屬性演算法具有靈活性,stl常用函式過載機制為演算法提供兩種形式,演算法的第一種形式使用的是常規操作來實現目標。在第二種形式中,演算法可以根據使用者指定的準則對元素進行處理。這種準則是通過函式物件來傳遞的。函式物件世紀上是過載了operator 的類模版。stl提供了許多函式物件,這些物件包含...

STL 函式物件

一 函式物件 functor stl中提供了一元和二元函式的兩種functor,通過unary function和binary function提供了這兩種不同引數數量的functor的基本結構,在這兩個型別中,分別內嵌定義一元和二元函式操作在模版推演的時候需要用到的typedef.一元函式的定義為...

STL 函式物件

4.1函式物件 4.1.1函式物件概念 過載函式呼叫操作符的類,其物件常稱為函式物件 函式物件使用過載的 時,行為類似函式呼叫,也叫仿函式 本質 函式物件 仿函式 是乙個類,不是函式 函式物件使用 特點 函式物件在使用時,可以像普通函式那樣呼叫,可以有引數,可以有返回值 函式物件超出普通函式概念,函...