如何初始化std :: map一次,以便它可以被类的所有对象使用?

时间:2010-01-11 22:26:20

标签: c++ static-members stdmap

我有一个枚举StackIndex定义如下:

typedef enum 
{
    DECK,
    HAND,
    CASCADE1,
    ...
    NO_SUCH_STACK
} StackIndex;

我创建了一个名为MoveSequence的类,它是std::deque形式的一堆元组的<StackIndex, StackIndex>的包装。

class MoveSequence
{
    public:
        void AddMove( const tpl_move & move ){ _m_deque.push_back( move ); }
        void Print();
    protected:
    deque<tpl_move> _m_deque;
};

我以为我可以创建std::map类的静态MoveSequence成员,该成员会将StackIndex翻译为std::string,供Print()使用功能。但是当我尝试时,我收到了错误:

"error C2864: 'MoveSequence::m' : only static const integral data members can be initialized within a class"

如果无法将std :: map创建为静态成员,是否有另一种方法可以创建std :: map,将StackIndex转换为可用于std::string的{​​{1}}打印出MoveSequence个对象?

感谢

Beeband。

4 个答案:

答案 0 :(得分:6)

您需要将初始化移动到源文件中:

// header
struct foo
{
    typedef std::map<unsigned, std::string> the_map;
    static const the_map m;
};

// source
const foo::the_map foo::m(...);

但是你要初始化它。 C ++ 0x删除了这个限制。

请记住Boost.Assign让这很容易:

#include <boost/assign.hpp>
const foo::the_map foo::m = boost::assign::map_list_of(1, "a")(2, "b");

答案 1 :(得分:3)

您可以使std :: map成为该类的静态成员。你不能做的是在类定义中初始化它。请注意,这是错误告诉您的内容:

  

错误C2864:'MoveSequence :: m':只有静态const积分数据成员可以在类中 *初始化*

所以,你想在标题中加上这个:

class MoveSequence
{
    static std::map<StackIndex, std::string> _m_whatever;
};

然后在源(.cpp)文件中你想要这个:

std::map<StackIndex, std::string> MoveSequence::_m_whatever( ..constructor args.. );

答案 2 :(得分:1)

正如其他人所建议的那样,您需要在C ++源文件中创建一个静态的地图实例。在初始化时,我建议在MoveSequence中创建一个静态函数:

class MoveSequence {

   static void InitMap() {
      if ( m_map.size() == 0 ) {
           m_map.insert( std::make_pair( DECK, "deck" ) );
            m_map.insert( std::make_pair( HAND, "hand" ) );
      }
   }
   ...
};

然后,您可以从MoveSequence的构造函数中调用它。

哦,BTW不需要枚举上的typedef:

enum StackIndex {
  ...
};

答案 3 :(得分:1)

我认为你不想要一个std :: map(尽管这里的所有其他答案都是关于如何做到的好)。听起来你只需要一个静态的C字符串数组,其中索引是枚举值。

const char* const stacknames[] = 
{
    "deck",
    "hand",
    "cascade1"
};

然后stacknames [DECK]是“deck”等等。