2015-11-13 137 views
0

早上好,我被困在正确的方式使用地图。C++地图比较

形势

具有独特的ID和其他两位代码的数据库表

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

,填补了地图正确,我这样定义它:

map<long, MyObject> 

哪里关键是我的ID和对象拥有所有的东西。地图工作正常,我加载所有的行,我很容易在里面导航。

烦恼

麻烦来当我需要使用一个标准这不是关键,但该行进行排序:

  1. 类型
  2. 名称

环顾互联网我发现我应该:

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

我做了第1步,但没有成功(它从未被调用过)。我正在努力做到这一点,但成效不大。 我会粘贴一些代码,以帮助:

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。 任何帮助表示赞赏。

回答

1

std::map不是一个多索引关联容器。它的find方法(和其他事物)使用该键作为搜索条件。没有可能指定另一个搜索条件。这就是为什么它是一个“单索引查找表”。可以使用Boost.MultiIndex。它是为你的情况而设计的,并且支持多个索引(顾名思义),既独特又不唯一。

或者你可以使用不同键的多个映射实例。如果钥匙不是唯一的,你需要std::multimap

+0

我还是不明白:ID是唯一的,Type和Name不是,为什么使用多个索引?我不应该重新定义排序标准吗,或者我错过了什么? – IssamTP

+0

@IssamTP:详细说明了答案 –

+0

基本上我应该定义类似于:class CKey {long id;长型;字符串名称;运算符<(CKey one,CKey two){/ * mysort criteria * /}},即使我在访问成员时遇到问题。非常感谢。 – IssamTP

0

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

而且,如果任何帮助表示赞赏,我会强烈建议你做一个

typedef long MyId; 

,并使用VS 2015年。

+0

使用VS2015是不可能的,现在。 – IssamTP

0

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

我的第一个想法是构建一个支持你的表模式的类。

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

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

但它听起来很糟糕。一旦您的表格发生变化,您应该复印。因此,您为什么只使用数据库order by获得结果?

+0

代码未更新,对不起。 – IssamTP

+0

没有你的话 – onebraveman

+0

代码更新,查询未更新。 – IssamTP