2016-02-08 80 views
1

有沒有什麼辦法可以使用map.find()/ map.count()算法爲一個鍵,它是類的對象的類型?對一個類使用map.find()和count()方法,這是一個類對象類型

我的multimap由雙對組成 - map.<myClass, enum>和myClass有一些成員,例如Filename。我想在我的地圖中搜索重複的文件名,並且我已經閱讀find()和count()函數爲鍵執行操作,但是可以實現它們以搜索密鑰的成員?

下面是一些代碼:

CDirectory (string n) { 
       fp.open (n, ios::in); 
       string dirName, fileName, fType; 
       int fileSize; 
       fp >> dirName; 
       m_strDirectory = dirName; 
       while (fp >> fileName >> fileSize >> fType) { 
         CFile obj (fileName, fileSize); 
         if (fType == "Archive") 
        filetype = Filetype::Archive; 
       else if (fType == "Hidden") 
        filetype = Filetype::Hidden; 
       else if (fType == "ReadOnly") 
        filetype = Filetype::ReadOnly; 
       else if (fType == "System") 
        filetype = Filetype::System; 
       else 
        filetype = Filetype::FileNotSupported; 
         m_DirectoryMap.insert(pair<CFile, Filetype>(CFile(obj.getFileName(), obj.getFileSize()), Filetype(filetype))); 
       } 
       multimap<CFile, Filetype>::iterator p = m_DirectoryMap.begin(); 
       while (p != m_DirectoryMap.end()) { 
       cout << endl << p->first.getFileName() << '\t' << p->first.getFileSize() << '\t' << p->second << endl; 
       ++p; 
       } 
    } 

這是第二類的構造,其具有對多重映射(的另一個類,枚舉>物件)。

這裏是第一類:

class CFile { 
    string m_strFile; 
    unsigned int m_size; 
public: 
    CFile() { m_strFile = ""; m_size = 0; } 
    CFile (string name, int size) { m_strFile = name; m_size = size; } 
    string getFileName() const { return m_strFile; } 
    int getFileSize() const { return m_size; } 
    void setFileSize (int size) { m_size = size; } 
    bool operator< (CFile& obj) { 
     return (m_size < obj.m_size); 
    } 
    bool operator== (const CFile& obj) { 
     return (m_size == obj.m_size); 
    } 
    friend ostream& operator<< (ostream& ost, const CFile& obj) { 
     return ost << obj.m_strFile << obj.m_size; 
    } 
    friend istream& operator>> (istream& ist, CFile& obj) { 
     return ist >> obj.m_strFile >> obj.m_size; 
    } 
    static bool Greater(const CFile& obj1, const CFile& obj2) { 
     if (obj1.m_size > obj2.m_size) 
      return true; 
     else 
      return false; 
    } 
}; 

我想找到的string m_strFile複印件;

+0

這將是,如果你更好可以發佈一些代碼,最好是[最小,完整和可驗證示例](http://stackoverflow.com/help/mcve)。 –

+0

你想要的是std :: find_if(http://www.cplusplus.com/reference/algorithm/find_if/) – kfsone

+0

查看我的評論Richard Hodge的答案,關於你的操作符重載。至於使用一個比較來存儲地圖與搜索地圖...你不能通過地圖的查找功能進行搜索,因爲該功能正在使用二叉樹搜索。你需要使用find_if,它將通過樹線性地前進以找到對象。 –

回答

3

A std::multimap通過Predicate(其調用操作符引用Key類型的兩個對象)的函數對象比較密鑰。

std::multimap的默認謂詞是std::less<>,這就是地圖通常按升序鍵排序的原因。

爲了讓您的按鍵具有可比性,您需要在地圖的模板參數列表(第三個位置)中指定自定義謂詞,或者爲您的類指定一個<運算符。

那麼你會在對的羣體,如通過地圖迭代:

struct MyKey 
{ 
    MyKey(std::string fname) : _filename { std::move(fname) } {} 
    const std::string& filename() const { return _filename; } 

    private: 
     std::string _filename; 
}; 

// define a predicate to order the map 
struct order_by_filename { 
    bool operator()(const MyKey& l, const MyKey& r) const { 
    return l.filename() < r.filename(); 
    } 
}; 

struct DataObject {}; 

std::multimap<MyKey, DataObject, order_by_filename> my_map; 

void strip_duplicates() 
{ 
    for(auto current = my_map.begin() ; current != my_map.end() ;) 
    { 
     auto range = my_map.equal_range(current->first); 
     // range is a std::pair containing the first and last iterator 
     // of the range with equal keys 
     auto num_items = range.second - range.first; 
     if (num_items > 1) { 
      // strip duplicates 
      my_map.erase(std::next(range.first), range.second); 
     } 
     // move to next range of keys 
     current = range.second; 
    } 
} 

的完整性,還有一種方法消除重複,而無需使用equal_range

void erase_all_but_one(std::multimap<Key, Value>& mmap, const Key& to_erase) 
{ 
    auto ifind = mmap.find(to_erase); 
    if (ifind == mmap.end()) return; 
    for(ifind = std::next(ifind) ; ifind != mmap.end() && ifind->first == to_erase ;) 
    { 
    // NOTE: take a copy of the advanced iterator BEFORE erasing 
    // the iterator. 
    auto inext = std::next(ifind); 
    mmap.erase(ifind); 
    ifind = inext; 
    } 
} 
+0

請不要重寫相等運算符來做任何事情,而只是比較對象的完整的,可觀察的狀態。它完全軟管維修。改用地圖的謂詞功能。 –

+0

@CrazyEddie同意。我很懶。固定。 –

相關問題