C++ 地图比较

C++ map comparsion

早上好,我无法正确使用地图。

情况

具有唯一 ID 和另外两个代码的数据库 table

ID (long) | Type (long) | Name (string)

为了正确填写地图,我是这样定义的:

map<long, MyObject>

其中 key 是我的 ID,对象包含所有内容。地图工作正常,我加载了所有行并在其中轻松导航。

烦恼

当我需要使用不是关键的条件对行进行排序时,问题就来了:

  1. 类型
  2. 姓名

上网查了一下发现应该:

  1. 为 MyObject 或...定义运算符<...
  2. 为我的地图定义另一种类型的比较器。

我执行了第 1 步,但没有成功(从未调用过)。我正在尝试执行第 2 点,但收效甚微。 我将粘贴一些代码来提供帮助:

class CSitoWebRigaVariante
{
public:
    bool    m_bSriDelete;
    bool    m_bSriVisibile;
    long    m_lSriId;
    long    m_lSriIdTipol;
    long    m_lSriCodGes;
    CString m_strSriCodMat;
public:
    CSitoWebRigaVariante(void);
    CSitoWebRigaVariante(const CSitoWebRigaVariante& cRiga);
    ~CSitoWebRigaVariante(void);
    bool operator<(const CSitoWebRigaVariante& cRiga);
    void operator=(const CSitoWebRigaVariante& cRiga);
    void Azzera(void);
    static void CaricaDaMDB(CDB* pDB, long lIdVM, map<long, CSitoWebRigaVariante>& cRighe);
};
typedef map<long, CSitoWebRigaVariante> CSWRighe;

///> Static method to fill a map.
void CSitoWebRigaVariante::CaricaDaMDB(CADODatabase* pDB, long lIdVM, map<long, CSitoWebRigaVariante>& cRighe)
{
    BOOL                    bValRit;
    CRecordset*         pRS;
    CSitoWebRigaVariante    riga;
    CString                 strInt;

    pRS = new CADORecordset(pDB);
    strInt.Format(_T("SELECT * FROM SITOWEB_RIVARMAT WHERE sri_idvarmat = %ld;"), lIdVM);
    cRighe.clear();
    if (pRS->Open(strInt, CADORecordset::openQuery) == TRUE && pRS->GetRecordCount() > 0)
    {
        while (pRS->IsEOF() == FALSE)
        {
            bValRit = pRS->GetFieldValue(_T("sri_id"), riga.m_lSriId);
            bValRit &= pRS->GetFieldValue(_T("sri_idtipol"), riga.m_lSriIdTipol);
            bValRit &= pRS->GetFieldValue(_T("sri_codges"), riga.m_lSriCodGes);
            bValRit &= pRS->GetFieldValue(_T("sri_codmat"), riga.m_strSriCodMat);
            bValRit &= pRS->GetFieldValue(_T("sri_delete"), riga.m_bSriDelete);
            bValRit &= pRS->GetFieldValue(_T("sri_visibile"), riga.m_bSriVisibile);
            cRighe.insert(pair<long, CSitoWebRigaVariante>(riga.m_lSriCodGes, riga));
            pRS->MoveNext();
        }
    }
    pRS->Close();
    delete pRS;
}

我正在使用 Visual Studio 2010,MFC。 感谢任何帮助。

std::map 不是多索引关联容器。它的 find 方法(和其他东西)使用键作为搜索条件。无法指定其他搜索条件。这就是为什么它是 "single-index lookup table".

您可以使用 Boost.MultiIndex。它专为您的情况而设计,支持多个索引(顾名思义),包括唯一索引和非唯一索引。

或者您可以使用具有不同键的多个地图实例。如果键不是唯一的,则需要 std::multimap.

我建议您使用地图作为模型(用于存储数据)。当需要显示信息时,按照需要显示的顺序输出即可。排序必须不是在存储项目的级别上进行,而是在显示它们的级别上进行。 虽然,在每种情况下您只需要重新排序一次。

此外,如果需要任何帮助,我强烈建议您做一个

typedef long MyId;

并使用 VS 2015。

map class 提供了构造函数的比较参数。您无法通过设置比较来完成您的目标,因为map 只支持按键比较功能。

我的第一个想法是构建一个 class 支持您的 table 架构。

class Example
{
    public:
        <your code>
        void sortByID();
        void sortByType();
        void sortByName();

    private:
        long ID_;
        long Type_;
        string Name_;
};

但这听起来很糟糕。一旦你的 table 发生变化,你应该很难 copy.So 为什么你只使用数据库 order by 来获得结果?