将普通成员变量转换为静态成员变量会导致问题
我曾经有一个普通的成员变量,它在构造函数中初始化如下:
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>c:\program files\microsoft Visual Studio 10.0\vc\include\utility(163): 错误 C2440: '正在初始化': 无法从 'int' 转换为 'GMProject::GMProjectMemFn '
这是关于 NULL 的转换。但这不应该是可能的吗?为什么这是不可能的(但在以前的方法中是不可能的)? 我应该在这里使用显式强制转换吗?
编辑: GMProjectMemFn 定义如下:
typedef void (GMProject::*GMProjectMemFn)(const pTree&) const;
pTree 是一个容器。
I used to have a normal member variable, which was initialized in the constructors as following:
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;
The variable is a map with as key strings, and as data member-function-pointers. This worked perfectly fine. However as said I believe this map should be static (?) - the reason for the map is just to identify what the program should do during reading of a file. - NULL meaning "do nothing special".
So I changed it to the following:
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());
Where those things are declared in the header:
static const std::map<std::string, GMProjectMemFn> ResourceSaveFunctions;
static std::map<std::string, GMProjectMemFn> ResourceSaveFunctions_INIT();
Now compiling suddenly brings up a lot of errors.
1>c:\program files\microsoft visual studio 10.0\vc\include\utility(163): error C2440: 'initializing' : cannot convert from 'int' to 'GMProject::GMProjectMemFn '
Which is about the conversion of NULL. However shouldn't this be just possible? Why is this not possible (yet in the previous method it was)?
Should I use an explicit cast here?
EDIT:
GMProjectMemFn defined as following:
typedef void (GMProject::*GMProjectMemFn)(const pTree&) const;
pTree being a container.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
std::make_pair
创建一个pair
,其中类型T1
和T2
是从隐式推导出来的参数的类型。NULL
扩展为0
(或0L
),因此在您的情况下make_pair
返回一个pair
(或pair
)。然后,您尝试将该
pair
传递给map::insert()
但这需要一个pair
。std::pair
有一个通用的复制构造函数,它将尝试对该对的每个成员进行隐式转换:但在您的情况下,这需要将
const int&
转换为指针,这是不允许的。在您最初的情况下,您直接将
NULL
转换为定义良好的指针。明确输入您的
pair
应该可以解决此问题:std::make_pair
creates apair<T1, T2>
where the typesT1
andT2
are deduced implicitly from the types of the arguments.NULL
expands to0
(or0L
) so in your casemake_pair
returns apair<string, int>
(or apair<string, long>
).You then try passing that
pair<string, int>
tomap<string, GMProject::GMProjectMemFn>::insert()
but this expects apair<string, GMProjectMemFn>
.std::pair
has a general copy constructor which will attempt implicit conversion of each member of the pair:but in your case this requires converting a
const int&
to a pointer, which is not permitted.In your original case you were directly converting
NULL
into a pointer, which is well defined.Explicitly typing your
pair
should fix this:啊。 NULL 可能仅定义为文字 0,
make_pair
将其推导为整数,并且pair
无法转换为pair< /代码>。它可以通过operator[]进行赋值,因为(我猜)是从0到GMProjectMemFn的隐式转换。
因此,请尝试编写
make_pair(PATHS_IDENT, (GMProjectMemFn)0)
。ah. NULL is probably defined only as literal 0,
make_pair
deduces this to integer, andpair<int,int>
is not convertible topair<int,GMProjectMemFn>
. It worked with assignment through operator[] because (I guess) of implicit conversion from 0 toGMProjectMemFn
.So, try writing
make_pair(PATHS_IDENT, (GMProjectMemFn)0)
.