[問題] 請教operator()的意義

作者: Keitaro (動き出す時間...)   2014-11-22 17:36:16
開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
VC2008/2013
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
MFC
問題(Question):
請教operator()的意義
程式碼(Code):(請善用置底文網頁, 記得排版)
// 建立自訂的struct object
struct SiteInfo
{
CString SiteName;
int SiteID;
SiteInfo(CString name, int ID)
{
SiteName = name;
SiteID = ID;
}
};
// Functor
struct FindSiteByID
{
int SiteID;
FindSiteByID(int ID)
{
SiteID = ID;
}
bool operator()(SiteInfo& info)
{
return (SiteID == info.SiteID);
}
};
// 利用Functor在vector中找到自己要的東西
void FindSite(int SiteNum)
{
std::vector<SiteInfo> test_vector;
test_vector.clear();
for (int i = 1; i <= 10; i++)
{
CString name;
name.Format(_T("Site%d"), i);
test_vector.push_back(SiteInfo(name, i));
}
std::vector<SiteInfo>::iterator iter;
iter = std::find_if(test_vector.begin(), test_vector.end(),
FindSiteByID(SiteNum));
}
補充說明(Supplement):
版上各位好,不好意思小弟不才上來請教一下各位關於operator overloading跟
Functor的概念。
我在工作上看到同事把一群struct SiteInfo放進vector,
然後使用Functor搭配find_if去尋找自己要的東西。
我看了侯捷的STL書籍Functor的概念,就是把function包成物件來使用。
雖然大概體會到Functor的意思,但我還是覺得很抽象。
有兩個地方想請教一下版上各位先進
1. 我猜想find_if這一行的意思是這樣的
a. 首先FindSiteByID(SiteNum)會先建立一個暫時的struct物件, 把SiteNum塞進去
b. find_if內建的迴圈逐一把iterator指向的struct與暫時物件拿來比較是否正確
我看find_if的實作
template<class _InIt, class _Pr> inline
_InIt _Find_if(_InIt _First, _InIt _Last, _Pr _Pred)
{ // find first satisfying _Pred
for (; _First != _Last; ++_First)
if (_Pred(*_First))
break;
return (_First);
}
我不明白這一行
if (_Pred(*_First))
為什麼會去呼叫
FindSiteByID::operator()(SiteInfo& info)
可否請版上各位解釋一下operator()的意思?我無法體會這一點。
我瞭解FindSiteByID(SiteNum)會去找FindSiteByID的所有建構式中,
輸入引數int的那一個建構式。
但我不懂為什麼if (_Pred(*_First))會去找operator()?
2. 我工作上的project類似要尋找特定物件的功能很多,
我想說如果每一個都寫成一個strcut,會很難管理。
如果我建立一個新的class,把自己定義的functor全部包起來,
是否合適?
謝謝各位。
作者: legendmtg (CLANNAD)   2014-11-22 18:16:00
因為_Pred是已經建立的object 不是type
作者: Feis (永遠睡不著 @@)   2014-11-22 18:19:00
當 a 是個物件時, a(b) 會試著呼叫 a.operator()(b)寫很多個 struct 有錯嗎?
作者: legendmtg (CLANNAD)   2014-11-22 18:24:00
2看不太懂耶 什麼叫把functor全包起來 你是只想放在同個namespace下的意思 還是什麼....不想寫很多個就想辦法做成template吧
作者: LPH66 (-6.2598534e+18f)   2014-11-22 20:37:00
我猜原 PO 第二點想要的大概就是 namespace不過還是要原 PO 講一下他所謂的「很難管理」是什麼意思..
作者: suhorng ( )   2014-11-22 21:58:00
若 A 是個 type (例如 class A {...};), 那 A() 呼叫的就是建構子; 若 A 是個變數(如 MyObj A;), 那 A() 呼叫的就會是 A.operator()(...);
作者: dirkc (3781615)   2014-11-22 22:30:00
第二個問題是設計的大哉問,可能要看你會做的動作有哪些我的淺見是需要先釐清設計的概念模型,先確定哪些物件以及它們彼此間的關係,看狀況考慮用繼承或多型,template 或namespace
作者: LPH66 (-6.2598534e+18f)   2014-11-23 15:28:00
差別就只是在這個名字到底是什麼東西而已FindSiteByID 是個 class 名所以是這種行為_Pred 是個變數名所以是那種行為, 而它的型態是模版參數_Pr事實上在模版實現時代入 FindSiteByID 的正是這個 _Pr而不是代入到 _Pred; 那玩意也無法代入就是個變數名而已

Links booklink

Contact Us: admin [ a t ] ucptt.com