推 chun0826:沒錯...這個定義的FUNCTION.. 218.184.83.40 06/13
→ chun0826:可以是一個MEMBER FUNCTION嗎 218.184.83.40 06/13
> -------------------------------------------------------------------------- <
作者: khoguan (Khoguan Phuann) 看板: C_and_CPP
標題: Re: [問題] type compare
時間: Mon Jun 13 01:43:33 2005
※ 引述《aecho (星空下的鮪魚)》之銘言:
: ※ 引述《chun0826 (蛋頭 ︩》之銘言:
: : 可以是一個Class的Meber function嗎...
: : 還是一定要是GLOBE..(我現在是用GLOBE的方式解決)
: : 如果可以是一個Class的Member fuction..
: : sort(comp function)這裡要怎們寫..
: 查了一下書
: 對於書裡的內容 我的想法如下
: 如果list裡的東西是自己定義的class
: 那必須自己另外定義 operator < 的行為
: 這樣就可以用 sort()這個function
是的。list 中的 sort() 有兩個,一個不需參數的就是
aecho哥講的那樣使用就對了,很簡單。另一個要參數的,
就比較複雜,我寫了一個完整的程式供參考:
// user-defined function object for comparison
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
class MyObj {
public:
MyObj(int i=0) : data(i) {}
bool comp(const MyObj& other) const { // 假設所用的比較函式名為 comp
if (this->data < other.data) return true;
else return false;
}
friend ostream& operator<< (ostream& os, const MyObj& my);
private:
int data;
};
ostream& operator<< (ostream& os, const MyObj& my)
{
return os << my.data;
}
// 以下是重點
template <typename T>
class compf {
bool (T::*pcomp)(const T&) const;
public:
explicit compf(bool (T::*p)(const T&) const) : pcomp(p) {}
bool operator()(const T& t1, const T& t2) {
return (t1.*pcomp)(t2);
}
};
template <typename T>
compf<T> mem_comp(bool (T::*p)(const T&) const) {
return compf<T>(p);
}
int main()
{
list<MyObj> mylist;
for (int i = 9; i >= 1; --i)
mylist.push_back(MyObj(i)); // 放進 9 個元素做測試用
mylist.sort(mem_comp(&MyObj::comp)); // 注意寫法!
// 正確印出排序後的結果
copy(mylist.begin(), mylist.end(), ostream_iterator<MyObj>(cout, "\n");
}
可參考 The C++ Programming Language, chap. 18
或是專門講 STL 的書。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.130.208.166
→ khoguan:這個可不用看,我已另貼了簡易版220.130.208.166 06/13
> -------------------------------------------------------------------------- <
作者: chun0826 (蛋頭 ︩ 看板: C_and_CPP
標題: Re: [問題] type compare
時間: Mon Jun 13 02:12:36 2005
※ 引述《khoguan (Khoguan Phuann)》之銘言:
: ※ 引述《aecho (星空下的鮪魚)》之銘言:
: : 查了一下書
: : 對於書裡的內容 我的想法如下
: : 如果list裡的東西是自己定義的class
: : 那必須自己另外定義 operator < 的行為
: : 這樣就可以用 sort()這個function
: 是的。list 中的 sort() 有兩個,一個不需參數的就是
: aecho哥講的那樣使用就對了,很簡單。另一個要參數的,
: 就比較複雜,我寫了一個完整的程式供參考:
: // user-defined function object for comparison
: #include <iostream>
: #include <list>
: #include <iterator>
: using namespace std;
: class MyObj {
: public:
: MyObj(int i=0) : data(i) {}
: bool comp(const MyObj& other) const { // 假設所用的比較函式名為 comp
: if (this->data < other.data) return true;
: else return false;
: }
: friend ostream& operator<< (ostream& os, const MyObj& my);
: private:
: int data;
: };
: ostream& operator<< (ostream& os, const MyObj& my)
: {
: return os << my.data;
: }
: // 以下是重點
這段可以解釋一下嗎..
還有位什們要有這一段..
目的為何..
這一段應該不是我照抄就可以解決的吧..
: template <typename T>
: class compf {
: bool (T::*pcomp)(const T&) const;
: public:
: explicit compf(bool (T::*p)(const T&) const) : pcomp(p) {}
: bool operator()(const T& t1, const T& t2) {
: return (t1.*pcomp)(t2);
: }
: };
: template <typename T>
: compf<T> mem_comp(bool (T::*p)(const T&) const) {
: return compf<T>(p);
: }
: int main()
: {
: list<MyObj> mylist;
: for (int i = 9; i >= 1; --i)
: mylist.push_back(MyObj(i)); // 放進 9 個元素做測試用
: mylist.sort(mem_comp(&MyObj::comp)); // 注意寫法!
: // 正確印出排序後的結果
: copy(mylist.begin(), mylist.end(), ostream_iterator<MyObj>(cout, "\n");
: }
: 可參考 The C++ Programming Language, chap. 18
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
可以給一下作者嗎..
: 或是專門講 STL 的書。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 218.184.83.40
> -------------------------------------------------------------------------- <
作者: khoguan (Khoguan Phuann) 看板: C_and_CPP
標題: Re: [問題] type compare
時間: Mon Jun 13 02:37:39 2005
※ 引述《chun0826 (蛋頭 ︩》之銘言:
: ※ 引述《khoguan (Khoguan Phuann)》之銘言:
: : 是的。list 中的 sort() 有兩個,一個不需參數的就是
: : aecho哥講的那樣使用就對了,很簡單。另一個要參數的,
: : 就比較複雜,我寫了一個完整的程式供參考:
: : // user-defined function object for comparison
: : #include <iostream>
: : #include <list>
: : #include <iterator>
: : using namespace std;
: : class MyObj {
: : public:
: : MyObj(int i=0) : data(i) {}
: : bool comp(const MyObj& other) const { // 假設所用的比較函式名為 comp
: : if (this->data < other.data) return true;
: : else return false;
: : }
: : friend ostream& operator<< (ostream& os, const MyObj& my);
: : private:
: : int data;
: : };
: : ostream& operator<< (ostream& os, const MyObj& my)
: : {
: : return os << my.data;
: : }
: : // 以下是重點
: 這段可以解釋一下嗎..
: 還有位什們要有這一段..
: 目的為何..
就是為了要產生 function object 給 list 的 sort 用。
如果沒有 functio object 的概念,要說明這段程式的寫作技巧,
老實說不是簡單幾句能夠講完的。也許要面對面教幾個小時吧。
: 這一段應該不是我照抄就可以解決的吧..
如果你上面的比較函式是這樣宣告:
bool comp(const MyObj& other) const;
不管函式名稱(comp),只管傳回的 type 是 bool, 參數的 type 也是
const T& 那個 T 要是這個 class 的名字,而接著後面也要有 const.
也就是 const member function, 那麼下面這段就可以照抄。
當然最後面實際呼叫 sort 時,所用的參數要用對 class 及 function
名稱。
: : template <typename T>
: : class compf {
: : bool (T::*pcomp)(const T&) const;
: : public:
: : explicit compf(bool (T::*p)(const T&) const) : pcomp(p) {}
: : bool operator()(const T& t1, const T& t2) {
: : return (t1.*pcomp)(t2);
: : }
: : };
: : template <typename T>
: : compf<T> mem_comp(bool (T::*p)(const T&) const) {
: : return compf<T>(p);
: : }
: : int main()
: : {
: : list<MyObj> mylist;
: : for (int i = 9; i >= 1; --i)
: : mylist.push_back(MyObj(i)); // 放進 9 個元素做測試用
: : mylist.sort(mem_comp(&MyObj::comp)); // 注意寫法!
: : // 正確印出排序後的結果
: : copy(mylist.begin(), mylist.end(), ostream_iterator<MyObj>(cout, "\n");
: : }
: : 可參考 The C++ Programming Language, chap. 18
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
: 可以給一下作者嗎..
這是 C++ 的創造者 Bjarne Stroustrup 寫的 C++ 聖經。第三版
葉秉哲有中譯,評價極好。或者參考侯捷譯的 C++ Primer 第三版,
可是這書英文版第四版已經出了。新版中譯可能要再等一陣子。
: : 或是專門講 STL 的書。
也可參考「C++ 標準程式庫」一書,侯捷中譯。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.130.208.166
→ khoguan:馬上貼個簡易版上來,請稍候220.130.208.166 06/13
> -------------------------------------------------------------------------- <
作者: prac (翔) 看板: C_and_CPP
標題: Re: [問題] type compare
時間: Mon Jun 13 02:32:15 2005
※ 引述《chun0826 (蛋頭 ︩》之銘言:
: ※ 引述《khoguan (Khoguan Phuann)》之銘言:
: : 是的。list 中的 sort() 有兩個,一個不需參數的就是
: : aecho哥講的那樣使用就對了,很簡單。另一個要參數的,
: : 就比較複雜,我寫了一個完整的程式供參考:
: : // user-defined function object for comparison
: : #include <iostream>
: : #include <list>
: : #include <iterator>
: : using namespace std;
: : class MyObj {
: : public:
: : MyObj(int i=0) : data(i) {}
: : bool comp(const MyObj& other) const { // 假設所用的比較函式名為 comp
: : if (this->data < other.data) return true;
: : else return false;
: : }
: : friend ostream& operator<< (ostream& os, const MyObj& my);
: : private:
: : int data;
: : };
: : ostream& operator<< (ostream& os, const MyObj& my)
: : {
: : return os << my.data;
: : }
: : // 以下是重點
: 這段可以解釋一下嗎..
: 還有位什們要有這一段..
: 目的為何..
: 這一段應該不是我照抄就可以解決的吧..
ostream 不能針對 MyObj 這個物件做操作
只能對常見的data type 進行處理(如int...)
須寫個function來定義 << operator的目的
在此例 operator<< 即是處理"data" 這個 private variable(data type 為int)
: : template <typename T>
: : class compf {
: : bool (T::*pcomp)(const T&) const;
: : public:
: : explicit compf(bool (T::*p)(const T&) const) : pcomp(p) {}
: : bool operator()(const T& t1, const T& t2) {
: : return (t1.*pcomp)(t2);
: : }
: : };
: : template <typename T>
: : compf<T> mem_comp(bool (T::*p)(const T&) const) {
: : return compf<T>(p);
: : }
: : int main()
: : {
: : list<MyObj> mylist;
: : for (int i = 9; i >= 1; --i)
: : mylist.push_back(MyObj(i)); // 放進 9 個元素做測試用
: : mylist.sort(mem_comp(&MyObj::comp)); // 注意寫法!
: : // 正確印出排序後的結果
: : copy(mylist.begin(), mylist.end(), ostream_iterator<MyObj>(cout, "\n");
: : }
: : 可參考 The C++ Programming Language, chap. 18
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
: 可以給一下作者嗎..
: : 或是專門講 STL 的書。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 210.85.102.248
> -------------------------------------------------------------------------- <
作者: khoguan (Khoguan Phuann) 看板: C_and_CPP
標題: Re: [問題] type compare (簡易版程式)
時間: Mon Jun 13 03:34:12 2005
※ 引述《chun0826 (蛋頭 ︩》之銘言:
: ※ 引述《khoguan (Khoguan Phuann)》之銘言:
: : 是的。list 中的 sort() 有兩個,一個不需參數的就是
: : aecho哥講的那樣使用就對了,很簡單。另一個要參數的,
: : 就比較複雜,我寫了一個完整的程式供參考:
我真是小題大作,弄了複雜難懂的寫法造成原po的困擾。
真是不好意思。以下是簡單易懂版。技巧就是透過 global function
來包裹 member function。但願能解決他的問題。
理論上,這樣寫執行效率會比較差一點。但若資料不是極多,
應該感覺不出來。畢竟易理解較重要。
// using function pointer for list.sort()
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
class MyObj {
public:
MyObj(int i=0) : data(i) {}
bool comp(const MyObj& other) const { // 假設所用的比較函式名為 comp
if (this->data < other.data) return true;
else return false;
}
friend ostream& operator<< (ostream& os, const MyObj& my);
private:
int data;
};
ostream& operator<< (ostream& os, const MyObj& my)
{
return os << my.data;
}
// 原先的複雜寫法,簡單改用 global function 來做
bool mem_comp(const MyObj& a, const MyObj& b)
{
return a.comp(b);
}
int main()
{
list<MyObj> mylist;
for (int i = 9; i >= 1; --i)
mylist.push_back(MyObj(i)); // 放進 9 個元素做測試用
mylist.sort(&mem_comp); // 注意用法,不寫 & 也行
}
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.130.208.166
※ 編輯: khoguan 來自: 218.163.154.74 (01/23 20:31)
> -------------------------------------------------------------------------- <
作者: khoguan (Khoguan Phuann) 看板: C_and_CPP
標題: Re: [問題] type compare (簡易版程式)
時間: Mon Aug 15 16:53:01 2005
※ 引述《khoguan (Khoguan Phuann)》之銘言:
: ※ 引述《chun0826 (蛋頭 ︩》之銘言:
: 我真是小題大作,弄了複雜難懂的寫法造成原po的困擾。
: 真是不好意思。以下是簡單易懂版。技巧就是透過 global function
: 來包裹 member function。但願能解決他的問題。
: 理論上,這樣寫執行效率會比較差一點。但若資料不是極多,
: 應該感覺不出來。畢竟易理解較重要。
原po的問題是:
在一個 list container 中放了一些物件(假設 type 為 class MyObj),
class MyObj 本身已經提供了 comp() 成員函式可以比較 MyObj 物件
的大小,現欲利用此 comp() 函式來排列 list 元素的順序,如何呼叫
list::sort(...) 呢?
解法分兩種情形,
一、若 comp() 是 static member function 的話,
就直接將函式指標丟給 sort(), 亦即
mylist.sort(&MyObj::comp);
這個 comp() 長這樣:
class MyObje {
public:
//...
static bool comp(const MyObj& lhs, const MyObj& rhs)
{
return lhs.data < rhs.data;
}
//...
};
二、若 comp() 是 non-static member function 的話,
就利用 STL 的 <functional> 提供的 mem_fun_ref() adapter
來包裝一下。再丟給 sort(), 亦即
mylist.sort(mem_fun_ref(&MyObj::comp));
此 comp() 的宣告及定義見以下。我之前寫的做法竟然不知
利用 mem_fun_ref(),而另外弄了一個 global function 來
包裹 comp(), 殊無必要,徒然降低效能。
: // using function pointer for list.sort()
: #include <iostream>
: #include <list>
: #include <iterator>
#include <functional>
: using namespace std;
: class MyObj {
: public:
: MyObj(int i=0) : data(i) {}
: bool comp(const MyObj& other) const { // 假設所用的比較函式名為 comp
: if (this->data < other.data) return true;
: else return false;
//上面令人感到 Orz 的兩行改成一行即可
return data < other.data;
: }
: friend ostream& operator<< (ostream& os, const MyObj& my);
: private:
: int data;
: };
: ostream& operator<< (ostream& os, const MyObj& my)
: {
: return os << my.data;
: }
: // 原先的複雜寫法,簡單改用 global function 來做
我原先複雜的寫法,其實是重新發明了不高明的輪子。
這個 mem_comp() 就不要了。
/*
: bool mem_comp(const MyObj& a, const MyObj& b)
: {
: return a.comp(b);
: }
*/
: int main()
: {
: list<MyObj> mylist;
: for (int i = 9; i >= 1; --i)
: mylist.push_back(MyObj(i)); // 放進 9 個元素做測試用
: mylist.sort(&mem_comp); // 注意用法,不寫 & 也行
// 改成
mylist.sort(mem_fun_ref(&MyObj::comp));
: }
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.130.208.168