[英]Comparison function for sorting member vector with sort()
我有一個像這樣的 class:
class test
{
vector<expr*> _exprs;
bool cmp(expr* e1, expr* e2);
ExprManager* mg;
}
和比較 function 是:
bool test::cmp(expr* e1, expr* e2)
{
return exprHight(mg, e1) < exprHight(mg, e2);
}
然后當我使用比較 function 對 _exprs 進行排序時(在另一個成員函數中)
sort(_exprs->begin(), _exprs->end(), cmp);
編譯器報告:
error: argument of type ‘bool (test::)(void*, void*)’ does not match ‘bool (test::*)(void*, void*)’
如何解決? 感謝提前。
定義排序謂詞的常規方法是作為函子。
讓您的 class 定義operator()
進行比較,您只需將 class 的實例傳遞給std::sort
。
所以真的,你需要做的就是像這樣定義 class :
class test
{
vector<expr*> _exprs;
bool operator()(expr* e1, expr* e2);
ExprManager* mg;
}
然后你可以像這樣調用sort
:
sort(_exprs->begin(), _exprs->end(), test());
或者,當然,使用test
class 的現有實例,而不是構建新實例。 但是您只需傳入一個 class 實例,根本不需要提及成員 function。
如果排序發生在另一個成員 function 中(從您對_exprs
的引用看起來是這樣),請寫
sort(_exprs->begin(), _exprs->end(), *this);
需要注意的一點是std::sort
與大多數其他標准庫算法一樣,復制謂詞 object,因此您的謂詞 class 必須能夠安全地處理復制(無論如何您的類都應該這樣做)
簡而言之,實現這一點的方法就是遵循“三法則”。
如果您的 class 定義了析構函數、復制構造函數或賦值運算符,那么它幾乎肯定應該定義所有這三個。
如果使用編譯器生成的復制構造函數,它只會復制您的類的指針成員,因此您將擁有兩個包含指向相同 object 的指針的對象。
如果 class 有一個在該指針上調用delete
的析構函數,那么最終會執行兩次。 這是一個錯誤。
如果您的 class 旨在可復制(並且大多數標准庫都要求這樣做),那么您必須定義適當的復制構造函數和賦值運算符以安全地實現它(例如,復制指針指向的資源,或使用智能而是指針)。
如果您的 class不是可復制的,那么您應該將復制構造函數和賦值運算符定義為private
,以便嘗試復制 class 將導致編譯時錯誤,而不是運行時崩潰。
你永遠不應該定義一個可以復制的 class ,但這樣做不正確。 要么定義必要的復制構造函數/賦值運算符/析構函數來處理復制,要么通過將復制 ctor/賦值運算符設為私有來使復制變得不可能。
在智能指針中包裝指向由 class 擁有的動態分配的 memory 的指針是一種免費獲得可復制性的簡單方法。
如果 class 只包含 RAII 對象,那么您根本不需要定義析構函數,因此三規則也不需要您定義復制構造函數和賦值運算符。
您需要進行test::cmp()
static :
class test {
// ...
static bool cmp( expr * lhs, expr * rhs );
};
或者,如果test::cmp()
由於某種原因不能是 static ,則需要使用( boost::
或std::tr1::
) bind()
來綁定cmp()
的(隱式) this
參數:
test * someInstance = this // other // something;
sort( _exprs->begin(), _exprs->end(),
bind( &test::cmp, someInstance, _1, _2 ) );
使用 operator() 然后將 '*this' 作為 Predicate 傳遞給 Sort 算法。
class test
{
vector<expr*> _exprs;
bool operator()(expr* e1, expr* e2);
ExprManager* mg;
}
sort(_exprs->begin(), _exprs->end(), *this);
無論您作為謂詞傳遞什么,都必須具有公共可訪問性,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.