将 MFC CMap 用于 CString int 对
Posted
技术标签:
【中文标题】将 MFC CMap 用于 CString int 对【英文标题】:using MFC CMap for CString int pairs 【发布时间】:2015-08-14 21:57:48 【问题描述】:我目前正在研究一个需要在值的友好名称和值本身之间来回转换的 DLL。由于这段代码在整个代码库中的许多地方都使用过,我想尽量保持简单,并在一个函数或对象中,所以我只需要声明一次。
从我的阅读来看,CMap
似乎是完成这项工作的工具,但我似乎无法发现任何模板参数的组合都可以无错误地编译。
我的值是CString
和int
。我尝试了以下定义:
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 < KEY, VALUE >
?其实
您正在使用原始日期类型,例如CMap
中的终极数据容器是CPair
,而CPair
的内部是KEY, VALUE
。因此,CMap
将真正存储一个KEY
,而不是ARG_KEY
。但是,如果您查看 MFC 源代码, 几乎所有在CMap
中传递的内部参数本身都是 用ARG_KEY
和ARG_VALUE
调用,因此,使用KEY &
作为ARG_KEY
似乎总是正确的,除非:int
、char
,其中按值传递没有区别(可能更快) 引用传递。 如果你使用CString
作为KEY
,你应该使用LPCTSTR
作为ARG_KEY
而不是CString &
,这个我们稍后再讨论。
编辑:Cristophe,分配的另一个选项是encodermap[_T("Encoder 1")] = 0;
,它适用于带有LPCTSTR
typedef 的单字节、多字节或Unicode。您还需要#include <tchar.h>
。
【讨论】:
以上是关于将 MFC CMap 用于 CString int 对的主要内容,如果未能解决你的问题,请参考以下文章
MFC中如何吧CString类型转换为double或int型??