我曾经有一个普通的成员变量,它在构造函数中初始化如下:
ResourceSaveFunctions[OBJECTS_IDENT] = NULL;
ResourceSaveFunctions[SPRITES_IDENT] = &GMProject::SaveSprite;
ResourceSaveFunctions[SOUNDS_IDENT] = &GMProject::SaveSound;
ResourceSaveFunctions[BACKGROUNDS_IDENT] = &GMProject::SaveBackground;
ResourceSaveFunctions[PATHS_IDENT] = NULL;
ResourceSaveFunctions[SCRIPTS_IDENT] = NULL;
ResourceSaveFunctions[FONTS_IDENT] = NULL;
ResourceSaveFunctions[TIMELINES_IDENT] = NULL;
ResourceSaveFunctions[ROOMS_IDENT] = NULL;
ResourceSaveFunctions["extension"] = &GMProject::SaveExtension;
ResourceSaveFunctions[INCLUDES_IDENT] = NULL;
ResourceSaveFunctions[TRIGGERS_IDENT] = NULL;
变量是一个带有键字符串的映射,以及作为数据成员函数指针的映射。这非常好。但是如上所述,我认为这个地图应该是静态的(?) - 地图的原因只是确定程序在读取文件时应该做什么。 - NULL意思是“什么都不做”。
所以我把它改成了以下内容:
std::map<std::string, GMProject::GMProjectMemFn> GMProject::ResourceSaveFunctions_INIT() {
std::map<std::string, GMProjectMemFn> tmp;
tmp.insert(std::make_pair(OBJECTS_IDENT,NULL));
tmp.insert(std::make_pair(SPRITES_IDENT, &GMProject::SaveSprite));
tmp.insert(std::make_pair(SOUNDS_IDENT, &GMProject::SaveSound));
tmp.insert(std::make_pair(BACKGROUNDS_IDENT, &GMProject::SaveBackground));
tmp.insert(std::make_pair(PATHS_IDENT, NULL));
tmp.insert(std::make_pair(SCRIPTS_IDENT, NULL));
tmp.insert(std::make_pair(FONTS_IDENT, NULL));
tmp.insert(std::make_pair(TIMELINES_IDENT, NULL));
tmp.insert(std::make_pair(ROOMS_IDENT, NULL));
tmp.insert(std::make_pair("extension", &GMProject::SaveExtension));
tmp.insert(std::make_pair(INCLUDES_IDENT, NULL));
tmp.insert(std::make_pair(TRIGGERS_IDENT, NULL));
return tmp;
}
const std::map<std::string, GMProject::GMProjectMemFn> GMProject::ResourceSaveFunctions(GMProject::ResourceSaveFunctions_INIT());
在标题中声明这些内容的地方:
static const std::map<std::string, GMProjectMemFn> ResourceSaveFunctions;
static std::map<std::string, GMProjectMemFn> ResourceSaveFunctions_INIT();
现在编译突然出现了很多错误。
1&gt; c:\ program files \ microsoft visual studio 10.0 \ vc \ include \ utility(163):错误C2440:'initializing':无法从'int'转换为'GMProject :: GMProjectMemFn'
关于NULL的转换。但是,这不应该是可能的吗?为什么这不可能(但在之前的方法中却是如此)? 我应该在这里使用明确的演员吗?
编辑: GMProjectMemFn定义如下:
typedef void (GMProject::*GMProjectMemFn)(const pTree&) const;
pTree是一个容器。
答案 0 :(得分:1)
std::make_pair
创建pair<T1, T2>
,其中T1
和T2
类型是从参数类型隐式推断出来的。 NULL
扩展为0
(或0L
),因此在您的情况下make_pair
会返回pair<string, int>
(或pair<string, long>
)。
然后尝试将pair<string, int>
传递给map<string, GMProject::GMProjectMemFn>::insert()
,但这需要pair<string, GMProjectMemFn>
。
std::pair
有一个通用的复制构造函数,它会尝试对该对的每个成员进行隐式转换:
template <class U, class V>
pair (const pair<U,V> &p) : first(p.first), second(p.second) { }
但在您的情况下,这需要将const int&
转换为指针,这是不允许的。
在原始案例中,您直接将NULL
转换为指针,该指针已明确定义。
明确键入pair
应该解决此问题:
tmp.insert(std::pair<std::string, GMProject::GMProjectMemFn>(TIMELINES_IDENT, NULL));
答案 1 :(得分:0)
啊。 NULL可能仅定义为文字0,make_pair
将其推导为整数,pair<int,int>
不能转换为pair<int,GMProjectMemFn>
。它通过operator []进行赋值,因为(我猜)从0到GMProjectMemFn
的隐式转换。
所以,试着写make_pair(PATHS_IDENT, (GMProjectMemFn)0)
。