将 MFC CMap 用于 CString int 对

Posted

技术标签:

【中文标题】将 MFC CMap 用于 CString int 对【英文标题】:using MFC CMap for CString int pairs 【发布时间】:2015-08-14 21:57:48 【问题描述】:

我目前正在研究一个需要在值的友好名称和值本身之间来回转换的 DLL。由于这段代码在整个代码库中的许多地方都使用过,我想尽量保持简单,并在一个函数或对象中,所以我只需要声明一次。

从我的阅读来看,CMap 似乎是完成这项工作的工具,但我似乎无法发现任何模板参数的组合都可以无错误地编译。

我的值是CStringint。我尝试了以下定义:

CMap<int, int, CString, CString> encodermap;

编译,但是当我尝试添加一个值时:

encodermap["Encoder 1"] = 0;

我收到以下编译器错误:

error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2501: 'encodermap' : missing storage-class or type specifiers
error C2040: 'encodermap' : 'int []' differs in levels of indirection from 'CMap<KEY,ARG_KEY,VALUE,ARG_VALUE>'

我尝试将CMap 更改为:

CMap<CString, CString, int, int> encodermap;

但我得到了同样的四个错误。

我确定我一定错过了什么,但我不知道是什么。

由于这项工作使用了 SDK,我需要 VS2003

【问题讨论】:

【参考方案1】:

问题

我认为您已经颠倒了键类型和 valye 类型。

您的原始声明将int 定义为使用operator[] 搜索的键。所以encodermap[0] = "Encoder 1"; 会起作用。

但是当您的编译器看到encodermap["Encoder 1"] = 0; 时,他会尝试找到一个operator[],该operator[] 接受char*(或char * 可以转换为的东西)并返回一个int。最后一条错误消息告诉您,他无法为您的地图找到这样的运算符。

使用 MSVC 2015,错误消息更加简洁:C2679。

解决方案

您应该使用CString 键和int 值定义您的CMap。要知道的诀窍是,对于 CString KEY,ARG_KEY 应该是 LPCWSTR 。所以正确的定义是:

CMap<CString, LPCWSTR, int, int> encodermap;

这允许在地图的operator[] 中使用CString 作为键。

现在,如果您在 Windows 上使用 MFC,您可能会使用 UNICODE 和宽字符(因此使用 LPCWSTR 而不是 LPCSTR)。调用运算符时,您必须使用 CString 或宽文本:

        encodermap[L"Encoder 1"] = 0;
        encodermap[CString("Encoder 2")] = 1;

【讨论】:

您可能还有兴趣进一步阅读CMap How-to 您应该使用CStringW 而不是CString,以匹配LPCWSTR 的编码。你仍然可以从一个狭窄的字符串文字构造一个CStringW,即CStringW("Encoder 2")(虽然这有点容易出错)。【参考方案2】:

试试这个:

CMap<CString, LPCTSTR, int, int> encodermap;

这篇 CodeProject 文章 CMap How-to 可能会有所帮助。

很多人对 CMap 的声明 CMap < KEY, ARG_KEY, VALUE, ARG_VALUE > 感到困惑,为什么不只是 CMap &lt; KEY, VALUE &gt;

其实CMap中的终极数据容器是CPair,而 CPair 的内部是 KEY, VALUE。因此,CMap 将真正存储一个 KEY,而不是 ARG_KEY。但是,如果您查看 MFC 源代码, 几乎所有在CMap 中传递的内部参数本身都是 用ARG_KEYARG_VALUE 调用,因此,使用KEY &amp; 作为ARG_KEY 似乎总是正确的,除非:

您正在使用原始日期类型,例如 intchar,其中按值传递没有区别(可能更快) 引用传递。 如果你使用CString作为KEY,你应该使用LPCTSTR作为ARG_KEY而不是CString &amp;,这个我们稍后再讨论。

编辑:Cristophe,分配的另一个选项是encodermap[_T("Encoder 1")] = 0;,它适用于带有LPCTSTR typedef 的单字节、多字节或Unicode。您还需要#include &lt;tchar.h&gt;

【讨论】:

以上是关于将 MFC CMap 用于 CString int 对的主要内容,如果未能解决你的问题,请参考以下文章

mfc中,如何将CString 转换成 string

mfc CMap 相关操作函数都有哪些?

MFC中如何吧CString类型转换为double或int型??

MFC中如何吧CString类型转换为double或int型?

MFC中的CString转char*

MFC,CString与intdouble 转换