很难在multimap <class object上使用max_element(min_element),=“”enum =“”>

时间:2016-02-10 13:48:49

标签: c++ algorithm dictionary multimap

我很难解决这个问题。我想在我的multimap中找到我的键的最大值和最小值(恰好是类的对象)。通过max和min我只能引用我的对象大小成员。我已经创建了一个比较器函数,在max_element(分别为min_element)函数上传递它,但是我得到了一些错误 - 类型&#39; const CFile&amp;& #39;来自类型&#39; std :: pair&lt;的表达式const CFile,CDirectory :: Filetype&gt;&#39;

我用自己的min和max函数实现修复了这个问题,但它对我来说似乎并不合适。这就是我想使用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;
}

3 个答案:

答案 0 :(得分:2)

std::max_element的comapre函数需要具有类似

的签名
QFileInfo my_dir(folderName);

if(my_dir.isDir() && my_dir.isWritable()){
    // Do something
}

其中

  

类型bool cmp(const Type1 &a, const Type2 &b); Type1必须使Type2类型的对象可以取消引用,然后隐式转换为它们。

因为您正在使用

ForwardIt

传递给std::max_element(m_DirectoryMap.begin(), m_DirectoryMap.end(), Greater); 的类型为Greater*std::multimap<CFile, Filetype>::iterator不是std::pair < const CFile, CDirectory::Filetype>,只需const CFile& obj1

你需要编写一个函数,需要两个Greater并比较它们。一个应该工作的函数可能看起来像

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()

答案 1 :(得分:2)

min_element / max_element对容器进行操作,不支持地图。他们将遍历所有元素并找到您正在寻找的元素。问题在于,当您拥有多图时,元素类型为pair<const CFile, FileType>,而不仅仅是CFile。只需修改您的Greater函数即可使用该对,并返回比较CFile对的结果。

如果你想要一个更通用/更短的解决方案,你可以定义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());
}

答案 2 :(得分:0)

在循环中使用multimap :: upper_bound应该更有效。