std::map 只读位置的分配

发布于 2024-09-06 22:20:53 字数 1667 浏览 4 评论 0 原文

我在一个类中有一个 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

不喜欢何必死缠烂打 2024-09-13 22:20:53

以下是当前 C++ 的一些替代初始化。当您说代码位于构造函数中时,我不确定“静态”初始化是什么意思。我有一些猜测,但这并不重要。选择你觉得“更干净”的东西。

if (m.empty()){
   m.insert (map<K,V>::value_type (k1, v1));
   m.insert (map<K.V>::value_type (k1, v1));
}

或者,

map<K,V>&  getmap() {
    static map<K,V>* m = 0;
    if (!m){
         m = new map<K,V>(); // never deleted.
        // insert.
    }
    return *m;
}

或者,

namespace /*anon*/ {
      map<K,V>* init_map () { 
         map<K,V>* m = new map<K,V>();
         // insertions here.
         return m; // return by val. can move in c++0x.
      }
}

map<K,V> Foo::m = *init_map ();

或者,

namespace /*anon*/ {
          map<K,V>* init_map () { 
             map<K,V>* m = new map<K,V>();
             // insertions here.
             return m; // return by val. can move in c++0x.
          }
}

map<K,V>&  Foo::get_map () { /* static singleton accessor */
     static map<K,V> * m = init_map ();
     return *m;
}

模式应该是明显的。你必须解决两个问题:一个是只初始化一次该死的小问题,另一个是防止静态初始化顺序失败的棘手问题。我个人的偏好类似于上面的第二种情况。

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.

if (m.empty()){
   m.insert (map<K,V>::value_type (k1, v1));
   m.insert (map<K.V>::value_type (k1, v1));
}

or,

map<K,V>&  getmap() {
    static map<K,V>* m = 0;
    if (!m){
         m = new map<K,V>(); // never deleted.
        // insert.
    }
    return *m;
}

or,

namespace /*anon*/ {
      map<K,V>* init_map () { 
         map<K,V>* m = new map<K,V>();
         // insertions here.
         return m; // return by val. can move in c++0x.
      }
}

map<K,V> Foo::m = *init_map ();

or,

namespace /*anon*/ {
          map<K,V>* init_map () { 
             map<K,V>* m = new map<K,V>();
             // insertions here.
             return m; // return by val. can move in c++0x.
          }
}

map<K,V>&  Foo::get_map () { /* static singleton accessor */
     static map<K,V> * m = init_map ();
     return *m;
}

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.

摇划花蜜的午后 2024-09-13 22:20:53

在 C++ 中,typedef GUI* CreateGUIFunc(); 不是一个带有未指定参数的函数,它是一个没有参数的函数。所以你的函数都不匹配该类型。您想要的是 typedef GUI* (*CreateGUIFunc)( std::string &filepath, int x, int y );

接下来,尝试使用 insertmap的成员函数而不是下标运算符,这样就无法结束不小心调用了常量版本。

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 is typedef 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.

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