在 multimap<Class object, enum> 上使用 max_element(min_element 也很困难)
Having a hard time using max_element (min_element also) on a multimap<Class object, enum>
我很难解决这个问题。我想在我的多重映射中找到我的键的最大值和最小值(它们恰好是 class 的对象)。通过最大值和最小值,我仅指我的对象大小成员。我制作了一个比较器函数,将其传递给 max_element(分别为 min_element)函数,但出现了一些错误—— 类型 [= 的引用初始化无效22=] 来自 'std::pair < const CFile, CDirectory::Filetype>'
类型的表达式
我用我自己的最小和最大函数实现解决了这个问题,但我觉得这不对。这就是为什么我想使用 min/max_element 算法...
这是我的示例程序::
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; }
/* stream manipulating and overloading operators here */
static bool Greater(const CFile& obj1, const CFile& obj2) {
return (obj1.getFileSize() > obj2.getFileSize());
}
bool operator< (CFile obj1, CFile obj2) {
return obj1.getFileName()<obj2.getFileName();
}
class CDirectory {
string m_strDirectory;
enum class Filetype {
Archive, Hidden, ReadOnly, System, FileNotSupported
};
Filetype filetype;
multimap <CFile, Filetype> m_DirectoryMap;
public:
friend std::ostream& operator<<(std::ostream& os, Filetype const type)
{
switch (type)
{
case Filetype::Archive:
os << "archive";
break;
case Filetype::Hidden:
os << "hidden";
break;
case Filetype::ReadOnly:
os << "read-only";
break;
case Filetype::System:
os << "system";
break;
case Filetype::FileNotSupported:
os << "not-supported";
break;
}
return os;
}
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;
}
}
void test() {
std::multimap<CFile, Filetype>::iterator result;
result = std::max_element(m_DirectoryMap.begin(), m_DirectoryMap.end(), Greater);
std::cout << "max element: " << result->first.GetFileSize() << "\t" << result->first.GetFileName();
}
};
int main () {
CDirectory obj("test.txt");
obj.test();
return 0;
}
std::max_element
的 comapre 函数需要像
这样的签名
bool cmp(const Type1 &a, const Type2 &b);
在哪里
The types Type1
and Type2
must be such that an object of type ForwardIt
can be dereferenced and then implicitly converted to both of them.
因为您正在使用
std::max_element(m_DirectoryMap.begin(), m_DirectoryMap.end(), Greater);
传递给 Greater
的类型是 *std::multimap<CFile, Filetype>::iterator
,它是 std::pair < const CFile, CDirectory::Filetype>
而不是 Greater
想要的 const CFile& obj1
。
您需要在其中编写一个函数,它接受两个 std::pair < const CFile, CDirectory::Filetype>
并比较它们。一个应该工作的函数看起来像
static bool GreaterPair(const std::pair<const CFile, CDirectory::Filetype> & lhs,
const std::pair<const CFile, CDirectory::Filetype> & rhs)
{
return Greater(lhs.first, rhs.first);
}
你也有错别字
std::cout << "max element: " << result->first.GetFileSize() << "\t" << result->first.GetFileName();
函数是 getFileSize()
而不是 GetFileSize()
。将其更改为
std::cout << "max element: " << result->first.getFileSize() << "\t" << result->first.getFileName();
min_element / max_element 在容器上运行并且不感知地图。他们将遍历所有元素并找到您要查找的元素。问题是,当您拥有多图时,元素类型是 pair<const CFile, FileType>
而不仅仅是 CFile
。只需修改您的 Greater
函数以使用该对,return 比较该对的 CFile
的结果。
如果你想要一个更 general/shorter 的解决方案,你可以为 std::multimap<Cfile, FileType>::value_type
定义一个别名,这将是我提到的那对。
应该看起来像这样
static bool Greater(const std::pair<const CFile, FileType>& a,
const std::pair<const CFile, FileType>& b) {
return (a.first.getFileSize() > b.first.getFileSize());
}
在循环中使用 multimap::upper_bound 应该更有效。
我很难解决这个问题。我想在我的多重映射中找到我的键的最大值和最小值(它们恰好是 class 的对象)。通过最大值和最小值,我仅指我的对象大小成员。我制作了一个比较器函数,将其传递给 max_element(分别为 min_element)函数,但出现了一些错误—— 类型 [= 的引用初始化无效22=] 来自 'std::pair < const CFile, CDirectory::Filetype>'
类型的表达式我用我自己的最小和最大函数实现解决了这个问题,但我觉得这不对。这就是为什么我想使用 min/max_element 算法...
这是我的示例程序::
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; }
/* stream manipulating and overloading operators here */
static bool Greater(const CFile& obj1, const CFile& obj2) {
return (obj1.getFileSize() > obj2.getFileSize());
}
bool operator< (CFile obj1, CFile obj2) {
return obj1.getFileName()<obj2.getFileName();
}
class CDirectory {
string m_strDirectory;
enum class Filetype {
Archive, Hidden, ReadOnly, System, FileNotSupported
};
Filetype filetype;
multimap <CFile, Filetype> m_DirectoryMap;
public:
friend std::ostream& operator<<(std::ostream& os, Filetype const type)
{
switch (type)
{
case Filetype::Archive:
os << "archive";
break;
case Filetype::Hidden:
os << "hidden";
break;
case Filetype::ReadOnly:
os << "read-only";
break;
case Filetype::System:
os << "system";
break;
case Filetype::FileNotSupported:
os << "not-supported";
break;
}
return os;
}
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;
}
}
void test() {
std::multimap<CFile, Filetype>::iterator result;
result = std::max_element(m_DirectoryMap.begin(), m_DirectoryMap.end(), Greater);
std::cout << "max element: " << result->first.GetFileSize() << "\t" << result->first.GetFileName();
}
};
int main () {
CDirectory obj("test.txt");
obj.test();
return 0;
}
std::max_element
的 comapre 函数需要像
bool cmp(const Type1 &a, const Type2 &b);
在哪里
The types
Type1
andType2
must be such that an object of typeForwardIt
can be dereferenced and then implicitly converted to both of them.
因为您正在使用
std::max_element(m_DirectoryMap.begin(), m_DirectoryMap.end(), Greater);
传递给 Greater
的类型是 *std::multimap<CFile, Filetype>::iterator
,它是 std::pair < const CFile, CDirectory::Filetype>
而不是 Greater
想要的 const CFile& obj1
。
您需要在其中编写一个函数,它接受两个 std::pair < const CFile, CDirectory::Filetype>
并比较它们。一个应该工作的函数看起来像
static bool GreaterPair(const std::pair<const CFile, CDirectory::Filetype> & lhs,
const std::pair<const CFile, CDirectory::Filetype> & rhs)
{
return Greater(lhs.first, rhs.first);
}
你也有错别字
std::cout << "max element: " << result->first.GetFileSize() << "\t" << result->first.GetFileName();
函数是 getFileSize()
而不是 GetFileSize()
。将其更改为
std::cout << "max element: " << result->first.getFileSize() << "\t" << result->first.getFileName();
min_element / max_element 在容器上运行并且不感知地图。他们将遍历所有元素并找到您要查找的元素。问题是,当您拥有多图时,元素类型是 pair<const CFile, FileType>
而不仅仅是 CFile
。只需修改您的 Greater
函数以使用该对,return 比较该对的 CFile
的结果。
如果你想要一个更 general/shorter 的解决方案,你可以为 std::multimap<Cfile, FileType>::value_type
定义一个别名,这将是我提到的那对。
应该看起来像这样
static bool Greater(const std::pair<const CFile, FileType>& a,
const std::pair<const CFile, FileType>& b) {
return (a.first.getFileSize() > b.first.getFileSize());
}
在循环中使用 multimap::upper_bound 应该更有效。