std :: map只读位置的分配

时间:2010-06-25 23:57:31

标签: c++ stl static map readonly

我在一个类中有static std::map<std::string, CreateGUIFunc>,它基本上包含识别gui类型的字符串,而CreateGUIFunc是对工厂函数的引用。

在我的构造函数中,我有

if ( m_factoryRef.size() == 0 ) {
  m_factoryRef["image"] = &CreateGUI<Image>;
  m_factoryRef["button"] = &CreateGUI<Button>;
}
...

但是,这给我一个错误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>())))))))’|

我不确定为什么这是一个只读任务。我也尝试将它改成普通成员只是为了看看它是否与静态有关,但同样的事情。

有什么问题?

编辑:一些定义使事情更清晰

// 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。如果有更简洁的方法来初始化静态地图,请告诉我。

2 个答案:

答案 0 :(得分:1)

以下是当前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;
}

模式应该是显而易见的。你必须解决两个问题:只有一次初始化该死的东西的琐碎问题,以及防止静态初始化命令惨败的棘手问题。我的偏好与上面的第二种情况类似。

答案 1 :(得分:0)

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

接下来,尝试使用地图的insert成员函数而不是下标运算符,这样就不会意外地调用常量版本。