在 class 对象类型的键上使用 map.find() 和 count()

Using map.find() and count() on a key, which is a class object type

有没有什么方法可以使用 map.find() / map.count() 算法作为 class 对象类型的密钥?

我的 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 的构造函数,它具有成对的多重映射(另一个 [=30= 的对象],枚举>)。

这是第一个 class:

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 的重复项;

A std::multimap 通过 Predicate(一个函数对象,其调用运算符引用两个 Key 类型的对象)来比较键。

std::multimap 的默认谓词是 std::less<>,这就是地图通常按升序键排序的原因。

为了使您的键具有可比性,您需要在地图的模板参数列表(第三个位置)中指定自定义谓词,或者为您的 class 提供一个 < 运算符。

然后您将成对地遍历地图,例如:

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;
  }
}