C++ 地图比较
C++ map comparsion
早上好,我无法正确使用地图。
情况
具有唯一 ID 和另外两个代码的数据库 table
ID (long) | Type (long) | Name (string)
为了正确填写地图,我是这样定义的:
map<long, MyObject>
其中 key 是我的 ID,对象包含所有内容。地图工作正常,我加载了所有行并在其中轻松导航。
烦恼
当我需要使用不是关键的条件对行进行排序时,问题就来了:
- 类型
- 姓名
上网查了一下发现应该:
- 为 MyObject 或...定义运算符<...
- 为我的地图定义另一种类型的比较器。
我执行了第 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
来获得结果?
早上好,我无法正确使用地图。
情况
具有唯一 ID 和另外两个代码的数据库 table
ID (long) | Type (long) | Name (string)
为了正确填写地图,我是这样定义的:
map<long, MyObject>
其中 key 是我的 ID,对象包含所有内容。地图工作正常,我加载了所有行并在其中轻松导航。
烦恼
当我需要使用不是关键的条件对行进行排序时,问题就来了:
- 类型
- 姓名
上网查了一下发现应该:
- 为 MyObject 或...定义运算符<...
- 为我的地图定义另一种类型的比较器。
我执行了第 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
来获得结果?