C++ 仿函數(shù)使用講解
一、問(wèn)題
先考慮一個(gè)簡(jiǎn)單的例子:假設(shè)有一個(gè)vector<string>,你的任務(wù)是統(tǒng)計(jì)長(zhǎng)度小于 5 的string的個(gè)數(shù),如果使用count_if函數(shù)的話(huà),你的代碼可能長(zhǎng)成這樣:
//統(tǒng)計(jì)長(zhǎng)度小于5的string的個(gè)數(shù)
bool LengthIsLessThanFive(const string& str) {
return str.length()<5;
}
int main()
{
vector<string> vec = { "asdd","asddsa","dssa","asd" };
int res1 = count_if(vec.begin(), vec.end(), LengthIsLessThanFive);
}
其中count_if函數(shù)的第三個(gè)參數(shù)是一個(gè)函數(shù)指針,返回一個(gè)bool類(lèi)型的值。
一般的,如果需要將任意長(zhǎng)度的參數(shù)也傳入的話(huà),我們可能將函數(shù)寫(xiě)成這樣:
//統(tǒng)計(jì)長(zhǎng)度小于len的string的個(gè)數(shù)
bool LengthIsLessThanFive(const string& str, int len) {
return str.length()< len;
}
這個(gè)函數(shù)看起來(lái)比前面一個(gè)版本更具有一般性,但是它不能滿(mǎn)足count_if函數(shù)的參數(shù)要求:
count_if要求的是僅帶有一個(gè)參數(shù)的函數(shù)指針作為它的最后一個(gè)參數(shù),編譯器會(huì)報(bào)錯(cuò)

所以問(wèn)題來(lái)了,怎么樣找到以上兩個(gè)函數(shù)的一個(gè)折中的解決方案呢?
二、一般的解決方案
我們考慮用一個(gè)全局變量
int maxLength=5;
//統(tǒng)計(jì)長(zhǎng)度小于len的string的個(gè)數(shù)
bool LenthIsLessThanCustom(const string& str) {
return str.length() < maxLength;
}
這段代碼看似很不錯(cuò),實(shí)則不符合規(guī)范,更重要的是,它不優(yōu)雅。原因有以下幾點(diǎn)要考慮:
1、容易出錯(cuò);
為什么這么說(shuō)呢,我們必須先初始化maxLength的值,才能繼續(xù)接下來(lái)的工作,如果我們忘了,則可能無(wú)法得到正確答案。此外,變量maxLength和函數(shù)LengthIsLessThan之間是沒(méi)有必然聯(lián)系的,編譯器無(wú)法確定在調(diào)用該函數(shù)前是否將變量初始化,給碼農(nóng)平添負(fù)擔(dān)。
2、沒(méi)有可擴(kuò)展性;
如果我們每遇到一個(gè)類(lèi)似的問(wèn)題就新建一個(gè)全局變量,尤其是多人合作寫(xiě)代碼時(shí),很容易引起命名空間污染(namespace polution)的問(wèn)題;當(dāng)范圍域內(nèi)有多個(gè)變量時(shí),我們用到的可能不是我們想要的那個(gè)。
3、全局變量的問(wèn)題;
每當(dāng)新建一個(gè)全局變量,即使是為了coding的便利,我們也要知道我們應(yīng)該盡可能的少使用全局變量,因?yàn)樗腸ost很高;而且可能暗示你這里有一些待解決的優(yōu)化方案。
三、新的解決方案——仿函數(shù)
如果我們不用全局變量,改如何解決這個(gè)問(wèn)題?
先來(lái)看仿函數(shù)的通俗定義:
仿函數(shù)(functor)又稱(chēng)為函數(shù)對(duì)象(function object)。是一個(gè)能行使函數(shù)功能的類(lèi)。仿函數(shù)的語(yǔ)法幾乎和我們普通的函數(shù)調(diào)用一樣,不過(guò)作為仿函數(shù)的類(lèi),都必須重載operator()運(yùn)算符,舉個(gè)例子:
class Func {
public:
void operator() (const string& str) const {
cout << str << endl;
}
};
int main()
{
Func myFunc;
myFunc("helloworld!");
}
仿函數(shù)其實(shí)是使用成員函數(shù)的方式解決這個(gè)問(wèn)題,因?yàn)槌蓡T函數(shù)可以很自然的訪(fǎng)問(wèn)成員變量
所以,對(duì)count_if問(wèn)題
struct ShorterThan {
public:
explicit ShorterThan(int maxLength) : length(maxLength) {}
bool operator() (const string& str) const {
return str.length() < length;
}
private:
const int length;
};
;
int main()
{
vector<string> vec = { "asdd","asddsa","dssa","asd" };
int res3 = count_if(vec.begin(), vec.end(), ShorterThan(5));
cout << res3 << endl;
}
另一個(gè)例子,比較大小
template<typename T> struct comp
{
bool operator()(T in1, T in2) const
{
return (in1 > in2);
}
};
int main()
{
comp<int> m_comp_objext;
cout << m_comp_objext(6, 3) << endl; //一、使用對(duì)象調(diào)用
cout << comp<int>()(6, 3) << endl; //二、使用臨時(shí)對(duì)象
return 0;
}

解釋?zhuān)浩渲械谝环N用法比較為大家所熟悉。 comp<int> m_comp_objext的意思是產(chǎn)生一個(gè)名為m_comp_objext的對(duì)象,m_comp_objext(6,3)則是調(diào)用其 operator(),并給予兩個(gè)參數(shù)6,3。第二種用法中的 comp<int>()意思是產(chǎn)生一個(gè)臨時(shí)(無(wú)名的)對(duì)象,之后的(6,3)才是指定兩個(gè)參數(shù)6,3。
參考:
https://blog.csdn.net/u013049912/article/details/84988027
https://blog.csdn.net/coolwriter/article/details/81533226
到此這篇關(guān)于C++ 仿函數(shù)使用講解的文章就介紹到這了,更多相關(guān)C++ 仿函數(shù)使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++異常處理方式實(shí)例詳解(超級(jí)詳細(xì)!)
程序有時(shí)會(huì)遇到運(yùn)行階段錯(cuò)誤,導(dǎo)致程序無(wú)法正常執(zhí)行下去,c++異常為處理這種情況提供了一種功能強(qiáng)大的而靈活的工具,下面這篇文章主要給大家介紹了關(guān)于C++異常處理方式的相關(guān)資料,需要的朋友可以參考下2023-04-04
深入淺析C語(yǔ)言與C++的區(qū)別與聯(lián)系
這篇文章主要為大家介紹了深入的分析了C語(yǔ)言與C++的區(qū)別與聯(lián)系,文中通過(guò)詳細(xì)的示例進(jìn)行了對(duì)比,以便大家更容易的看懂理解,有需要的朋友可以借鑒參考下2021-11-11
詳解C語(yǔ)言解決經(jīng)典問(wèn)題之兔子產(chǎn)子
有一對(duì)兔子,從出生后的第 3 個(gè)月起每個(gè)月都生一對(duì)兔子。小兔子長(zhǎng)到第 3 個(gè)月后每個(gè)月又生一對(duì)兔子,假設(shè)所有的兔子都不死,問(wèn) 30 個(gè)月內(nèi)每個(gè)月的兔子總數(shù)為多少?本文將用C語(yǔ)言解決這一經(jīng)典問(wèn)題,需要的可以參考一下2022-03-03
C++中常見(jiàn)容器類(lèi)的使用方法詳解(vector/deque/map/set)
C++中常見(jiàn)的容器類(lèi)有vector、list、deque、map、set、unordered_map和unordered_set。下面將舉例直接說(shuō)明各個(gè)容器的使用方法,希望對(duì)大家有所幫助2023-03-03
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之Hash散列表
這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之Hash散列表,散列表(哈希表)其思想主要是基于數(shù)組支持按照下標(biāo)隨機(jī)訪(fǎng)問(wèn)數(shù)據(jù),時(shí)間復(fù)雜度為O(1)的特性,可以說(shuō)是數(shù)組的一種拓展,需要的朋友可以參考下2023-08-08
C/C++實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何使用C/C++實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別,分別處理 32*32 文本數(shù)據(jù)集和mnist 28*28 png數(shù)據(jù)集,感興趣的小伙伴可以跟隨小編一起了解一下2023-10-10
OpenCV+Qt實(shí)現(xiàn)圖像處理操作工具的示例代碼
這篇文章主要介紹了利用OpenCV+Qt實(shí)現(xiàn)圖像處理操作工具,可以實(shí)現(xiàn)雪花屏、高斯模糊、中值濾波、毛玻璃等操作,感興趣的可以了解一下2022-08-08

