将普通成员变量转换为静态成员变量会导致问题

发布于 2024-12-17 21:20:02 字数 2524 浏览 0 评论 0原文

我曾经有一个普通的成员变量,它在构造函数中初始化如下:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无敌元气妹 2024-12-24 21:20:02

std::make_pair 创建一个 pair,其中类型 T1T2 是从隐式推导出来的参数的类型。 NULL 扩展为 0 (或 0L),因此在您的情况下 make_pair 返回一个 pair(或pair)。

然后,您尝试将该 pair 传递给 map::insert() 但这需要一个 pair

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));

std::make_pair creates a pair<T1, T2> where the types T1 and T2 are deduced implicitly from the types of the arguments. NULL expands to 0 (or 0L) so in your case make_pair returns a pair<string, int> (or a pair<string, long>).

You then try passing that pair<string, int> to map<string, GMProject::GMProjectMemFn>::insert() but this expects a pair<string, GMProjectMemFn>.

std::pair has a general copy constructor which will attempt implicit conversion of each member of the pair:

template <class U, class V>
    pair (const pair<U,V> &p) : first(p.first), second(p.second) { }

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:

tmp.insert(std::pair<std::string, GMProject::GMProjectMemFn>(TIMELINES_IDENT, NULL));
穿越时光隧道 2024-12-24 21:20:02

啊。 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, and pair<int,int> is not convertible to pair<int,GMProjectMemFn>. It worked with assignment through operator[] because (I guess) of implicit conversion from 0 to GMProjectMemFn.

So, try writing make_pair(PATHS_IDENT, (GMProjectMemFn)0).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文