我在一个类中有一个 static std::map ,该类基本上保存标识 gui 类型的字符串,而 CreateGUIFunc 是对工厂函数的引用。
然而,在我的构造函数中
if ( m_factoryRef.size() == 0 ) {
m_factoryRef["image"] = &CreateGUI<Image>;
m_factoryRef["button"] = &CreateGUI<Button>;
}
...
,这给了我一个错误,说分配只读位置 'GUIManager::m_factoryRef.std::map<_Key, _Tp, _Compare, _Alloc>::operator[] [with _Key = std::basic_string、std::allocator; >、_Tp = GUI*()、_Compare = std::less、std::allocator; > >, _Alloc = std::allocator, std::allocator; >, GUI*()> >](((const std::basic_string, std::allocator>&)(& std::basic_string ;, std::allocator >(((const char*)"image"), ((const std::allocator&)((const std::allocator*)(& ; std::allocator()))))))'|
我不确定为什么这是一个只读分配。我还尝试将其更改为普通成员,只是为了看看它是否与静态有关,但同样的事情。
问题是什么?
编辑:一些定义让事情变得更
// these are all private
typedef GUI* CreateGUIFunc();
template<class T>
GUI* GUIManager::CreateGUI( std::string &filepath, int x, int y ) {
return new T( filepath, x, y );
}
static std::map<std::string, CreateGUIFunc> m_factoryRef;
清晰如果有任何更清晰的方法来初始化静态地图,请告诉我。
I have a static std::map<std::string, CreateGUIFunc>
in a class that basically holds strings identifying gui types, and CreateGUIFunc is a reference to a factory function.
In my constructor I have
if ( m_factoryRef.size() == 0 ) {
m_factoryRef["image"] = &CreateGUI<Image>;
m_factoryRef["button"] = &CreateGUI<Button>;
}
...
However, this gives me an error saying assignment of read-only location ‘GUIManager::m_factoryRef.std::map<_Key, _Tp, _Compare, _Alloc>::operator[] [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = GUI*(), _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, GUI*()> >](((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)(& std::basic_string<char, std::char_traits<char>, std::allocator<char> >(((const char*)"image"), ((const std::allocator<char>&)((const std::allocator<char>*)(& std::allocator<char>())))))))’|
I'm not sure why this is a read-only assignment. I also tried changing it to a normal member just to see if maybe it had to do with it being static, but same thing.
What is the problem?
Edit: Some definitions to make things a bit more clear
// these are all private
typedef GUI* CreateGUIFunc();
template<class T>
GUI* GUIManager::CreateGUI( std::string &filepath, int x, int y ) {
return new T( filepath, x, y );
}
static std::map<std::string, CreateGUIFunc> m_factoryRef;
P.S. If there is any cleaner way to initialize a static map please let me know.
发布评论
评论(2)
以下是当前 C++ 的一些替代初始化。当您说代码位于构造函数中时,我不确定“静态”初始化是什么意思。我有一些猜测,但这并不重要。选择你觉得“更干净”的东西。
或者,
或者,
或者,
模式应该是明显的。你必须解决两个问题:一个是只初始化一次该死的小问题,另一个是防止静态初始化顺序失败的棘手问题。我个人的偏好类似于上面的第二种情况。
Here are some alternative initializations for current C++. I'm not sure what you mean by "static" initialization when you said your code is in a constructor. I have some guesses, but it doesn't matter. Choose what feels "cleaner" to you.
or,
or,
or,
The pattern should be obvious. You have to solve two problems: the trivial problem of initializing the damn thing only once, and the trickier problem of preventing the static initialization order fiasco. My person preference is something like the second case above.
在 C++ 中,
typedef GUI* CreateGUIFunc();
不是一个带有未指定参数的函数,它是一个没有参数的函数。所以你的函数都不匹配该类型。您想要的是typedef GUI* (*CreateGUIFunc)( std::string &filepath, int x, int y );
接下来,尝试使用
insert
map的成员函数而不是下标运算符,这样就无法结束不小心调用了常量版本。In C++,
typedef GUI* CreateGUIFunc();
isn't a function with unspecified parameters, it's a function with NO parameters. So none of your functions match that type. What you want istypedef GUI* (*CreateGUIFunc)( std::string &filepath, int x, int y );
Next, try using the
insert
member function of the map instead of the subscript operator, that way you can't end up calling the constant version by accident.