2011-02-03 34 views
2

我想寫一個函子,我可以傳遞給std :: sort,它會根據向量中對象的比較結果來排序表示另一個對象向量的向量的向量。而不是假設向量中的對象具有成員操作符<,我想傳入一個謂詞,比如我將它傳遞到std :: sort,如果我直接對對象向量進行排序。傳遞函子給一個函子

template <class T, class _Pr> 
class SortIndexVectorObjectsHelper : public std::binary_function<ULONG, ULONG, bool> 
{ 
    ULONG m_ulSize; 
    std::vector<T> & m_aItems; 
    BOOL m_bSortAscending; 
    _Pr m_Comp; 

public: 

    SortIndexVectorObjectsHelper(std::vector<T> & aItems, _Pr Comp) : m_aItems(aItems), m_Comp(Comp), m_ulSize(0) 
    { 
     m_ulSize = m_aItems.size(); 
    } 

    bool operator()(ULONG & rLeft, ULONG & rRight) 
    { 
     if (rLeft < m_ulSize && rRight < m_ulSize) 
     { 
      T & pLeft = m_aItems[rLeft]; 
      T & pRight = m_aItems[rRight]; 

      if (pLeft && pRight) 
      { 
       return m_Comp(pLeft, pRight); 
      } 
     } 
     return false; 
    } 


}; 

struct SortFooByX: public std::binary_function<CFoo,CFoo, bool> 
{ 
    BOOL m_bSortAscending; 

    SortFooByX(BOOL bSortAscending) 
    { 
     m_bSortAscending = bSortAscending; 
    } 

    bool operator()(CFoo & _Left, CFoo & _Right) 
    { 

     if (m_bSortAscending) 
     { 
     if (_Left.X() < _Right.X()) 
      return true; 
     } 
     else 
     { 
     if (_Left.X() > _Right.X()) 
        return true; 

      } 

      return false; 
    } 


}; 

std::sort(aFooIndicies.begin(), aFooIndicies.end(), SortIndexVectorObjectsHelper<CFoo, std::binary_function<CFoo, CFoo, bool> >(aFoo, SortFooByX(FALSE))); 

編譯這給我的錯誤是沒有一個2重載可以轉換所有的參數類型。

+0

我認爲是因爲你的operator()`應該接收兩個類型爲`const T&`的參數,並且你將它設計爲接收`ULONG`。 – 2011-02-03 18:41:26

+1

_Pr是保留的標識符;不要使用它。 – 2011-02-03 18:45:31

回答

0
std::sort(aFooIndicies.begin(), aFooIndicies.end(), SortIndexVectorObjectsHelper<CFoo, std::binary_function<CFoo, CFoo, bool> >(aFoo, SortFooByX(FALSE))); 

SortIndexVectorObjectsHelper中的第二個參數類型錯誤。該類型應該是SortFooByX,如下圖所示:

SortIndexVectorObjectsHelper<CFoo, SortFooByX> comparer(aFoo, SortFooByX(FALSE)); 
std::sort(aFooIndicies.begin(), aFooIndicies.end(), comparer); 

嘗試此。它現在應該工作。

0

比較運算符需要採用const引用。 const引用不能隱式轉換爲非const引用,所以編譯器說沒有與參數類型相匹配的有效重載。只需使用此代替:

bool operator()(const ULONG & rLeft, const ULONG & rRight) 

而且我建議你在其他類比較CFoo和CFoo相同。當你編寫一個通過引用接受參數的函數並且不修改這些參數的值時,最好總是使參考爲const,它會更清晰,更安全,限制更少。當它們是非常量時,你告訴世界你希望這些參數是可修改的,當它們不需要時,所以你限制了函數的可能用法,在這種情況下,這會導致問題。

正如其他人也提到的,你應該小心你的命名約定。一般來說,您應該避免使用前導下劃線_,因爲它們被用於特殊保留字或關鍵字的排序(雙引號下劃線通常用於編譯器特定指令等的保留字)。最好避免它,否則,最終可能會遇到非常奇怪的錯誤或可移植性問題。

0
template<class Lookup, class Compare> 
struct LookupCompare { 
    Lookup &lookup; 
    Compare cmp; 

    LookupCompare(Lookup &lookup, Compare cmp=Compare()) : lookup (lookup), cmp (cmp) {} 

    template<class T> 
    bool operator()(T const &a, T const &b) { 
    return cmp(lookup[a], lookup[b]); 
    } 
}; 

Example

struct Less { 
    template<class T> 
    bool operator()(T const &a, T const &b) { 
    return std::less<T>()(a, b); 
    } 
}; 

template<class Lookup> 
LookupCompare<Lookup, Less> lookup_compare(Lookup &lookup) { 
    return lookup; 
} 
template<class Lookup, class Compare> 
LookupCompare<Lookup, Compare> lookup_compare(Lookup &lookup, Compare cmp) { 
    return LookupCompare<Lookup, Compare>(lookup, compare); 
} 

int main() { 
    vector<int> lookup; 
    lookup.push_back(42); 
    lookup.push_back(3); 
    lookup.push_back(5); 

    vector<int> data; 
    data.push_back(0); 
    data.push_back(1); 
    data.push_back(2); 

    cout << data << '\n'; 
    sort(data.begin(), data.end(), lookup_compare(lookup)); 
    cout << data << '\n'; 

    return 0; 
} 

我不知道爲什麼你使用m_ulSize,所以我離開了這一點。我也大大簡化了,LookupCompare現在適用於10 SLOC。特別是,它不需要升序標誌,因爲您可以將std :: less替換爲std :: greater或注入一個「反轉」比較器。

相關問題