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

看板C_and_CPP作者 (動き出す時間...)時間11年前 (2014/11/22 17:36), 11年前編輯推噓5(5016)
留言21則, 5人參與, 最新討論串1/1
開發平台(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全部包起來, 是否合適? 謝謝各位。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.43.194.55 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1416648978.A.2DE.html

11/22 18:16, , 1F
因為_Pred是已經建立的object 不是type
11/22 18:16, 1F

11/22 18:19, , 2F
當 a 是個物件時, a(b) 會試著呼叫 a.operator()(b)
11/22 18:19, 2F

11/22 18:19, , 3F
寫很多個 struct 有錯嗎?
11/22 18:19, 3F

11/22 18:24, , 4F
2看不太懂耶 什麼叫把functor全包起來 你是只想放在
11/22 18:24, 4F

11/22 18:24, , 5F
同個namespace下的意思 還是什麼....
11/22 18:24, 5F

11/22 18:24, , 6F
不想寫很多個就想辦法做成template吧
11/22 18:24, 6F

11/22 20:37, , 7F
我猜原 PO 第二點想要的大概就是 namespace
11/22 20:37, 7F

11/22 20:38, , 8F
不過還是要原 PO 講一下他所謂的「很難管理」是什麼意思..
11/22 20:38, 8F
先感謝以上各位的指教。 我的疑問是這樣的 1. 建立物件時會呼叫建構式, 如果建構式不只一個, 就看輸入引數的數目跟型別來判斷要呼叫哪一個。 那麼,當我建立FindSiteByID物件時,因為我傳入的引數是一個int, 所以呼叫了 FindSiteByID::FindSiteByID(int ID) 那麼根據F版友所述

11/22 18:19, , 9F
當 a 是個物件時, a(b) 會試著呼叫 a.operator()(b)
11/22 18:19, 9F
請問為何是會去呼叫 FindSiteByID::operator()(SiteInfo& info) 而不是去尋找看有沒有這個建構式來用 FindSiteByID::FindSiteByID(SiteInfo& info) 還是說這兩個是一樣的呢?我不懂的就是這一點。 FindSiteByID m_struct(1) -> 呼叫建構式 FindSiteByID m_struct(info) -> 呼叫operator()(SiteInfo& info) why?? 2. 因為我的project裡面會對儲存SiteInfo的vector做一堆處理, 找出自己要的Site呼叫FindSiteByID只是其中一個。 我可能會寫 Struct InsertSite { std::vector<SiteInfo>& m_vector; InsertSite(std::vector<SiteInfo>& site_vector) { m_vector = site_vector; } void operator()(SiteInfo& info) { m_vector.push_back(info); } } 然後搭配std::for_each把所有建立起來的SiteInfo一次塞完。 如果不同的功能每一個都寫成一個functor,可能有數十個。 那麼是否我應該寫一個新的class把這些functor全部包進去管理? 謝謝各位。 ※ 編輯: Keitaro (114.43.194.55), 11/22/2014 21:37:46 ※ 編輯: Keitaro (114.43.194.55), 11/22/2014 21:41:45

11/22 21:58, , 10F
若 A 是個 type (例如 class A {...};), 那 A() 呼叫的就
11/22 21:58, 10F

11/22 21:59, , 11F
是建構子; 若 A 是個變數(如 MyObj A;), 那 A() 呼叫的就
11/22 21:59, 11F

11/22 21:59, , 12F
會是 A.operator()(...);
11/22 21:59, 12F

11/22 22:30, , 13F
第二個問題是設計的大哉問,可能要看你會做的動作有哪些
11/22 22:30, 13F

11/22 22:32, , 14F
我的淺見是需要先釐清設計的概念模型,先確定哪些物件以及
11/22 22:32, 14F

11/22 22:33, , 15F
它們彼此間的關係,看狀況考慮用繼承或多型,template 或
11/22 22:33, 15F

11/22 22:33, , 16F
namespace
11/22 22:33, 16F
第一個問題我想明白了: 這一行 FindSiteByID(SiteNum) 相當於 FindSiteBy site(SiteNum) 建立物件暫時物件,呼叫建構式 FindSiteByID::FindSiteByID(int ID) 但是for_each的實作裡面這一行 if (_Pred(*_First)) 其中的_Pred代表建構式建立起來的暫時物件,已經把物件建立完了, 此時塞SiteInfo進去,才會去呼叫     FindSiteByID::operator()(SiteInfo& info) 是不是這樣呢? 第二個問題我想試著先寫寫看,非常感謝以上指點的各位版友! ※ 編輯: Keitaro (114.43.215.48), 11/23/2014 13:49:14

11/23 15:28, , 17F
差別就只是在這個名字到底是什麼東西而已
11/23 15:28, 17F

11/23 15:30, , 18F
FindSiteByID 是個 class 名所以是這種行為
11/23 15:30, 18F

11/23 15:30, , 19F
_Pred 是個變數名所以是那種行為, 而它的型態是模版參數_Pr
11/23 15:30, 19F

11/23 15:31, , 20F
事實上在模版實現時代入 FindSiteByID 的正是這個 _Pr
11/23 15:31, 20F

11/23 15:32, , 21F
而不是代入到 _Pred; 那玩意也無法代入就是個變數名而已
11/23 15:32, 21F
文章代碼(AID): #1KS5aIBU (C_and_CPP)