在键上使用 map.find() 和 count(),这是一种类对象类型
Using map.find() and count() on a key, which is a class object type
有什么方法可以将map.find()/map.count()算法用于类的对象类型的键?
我的多重映射由对组成 - map.<myClass, enum>
和 myClass 有一些成员,例如文件名。我想在我的地图中搜索重复的文件名,我已经读到 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;
}
}
这是第二个类的构造函数,它有一个对的多重映射(另一个类的对象,enum>)。
这是第一类:
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
的重复项;
通过Predicate
(其调用运算符引用两个类型为 Key
的对象)比较键的std::multimap
。
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;
}
}
相关文章:
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 模板元程序查找相似的连续类型名称
- 任何种类的分数 在任何类型的订单中
- 2 种模板相关类型种类的差异
- C++每帧更新和复制一系列值.我应该使用哪种类类型
- 在键上使用 map.find() 和 count(),这是一种类对象类型