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

C++ 如何初始化std::map一次,以便它可以被类的所有对象使用?,c++,static-members,stdmap,C++,Static Members,Stdmap,我有一个enum StackIndex,定义如下: typedef enum { DECK, HAND, CASCADE1, ... NO_SUCH_STACK } StackIndex; 我已经创建了一个名为MoveSequence的类,它是一个std::deque格式的元组的包装器 如果无法将std::map创建为静态成员,是否有其他方法可以创建std::map,将StackIndex转换为可用于打印MoveSequence对象的std::stri

我有一个enum StackIndex,定义如下:

typedef enum 
{
    DECK,
    HAND,
    CASCADE1,
    ...
    NO_SUCH_STACK
} StackIndex;
我已经创建了一个名为
MoveSequence
的类,它是一个
std::deque
格式的元组的包装器

如果无法将std::map创建为静态成员,是否有其他方法可以创建std::map,将
StackIndex
转换为可用于打印
MoveSequence
对象的
std::string

谢谢


Beeband.

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

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

// source
const foo::the_map foo::m(...);
//头
结构foo
{
typedef std::映射_映射;
静态常数映射m;
};
//来源
常量foo::映射foo::m(…);
无论您想如何初始化它。C++0x删除了此限制

请记住,这非常容易:

#include <boost/assign.hpp>
const foo::the_map foo::m = boost::assign::map_list_of(1, "a")(2, "b");
#包括
常量foo::映射foo::m=boost::赋值::映射列表(1,“a”)(2,“b”);

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

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

// source
const foo::the_map foo::m(...);
//头
结构foo
{
typedef std::映射_映射;
静态常数映射m;
};
//来源
常量foo::映射foo::m(…);
无论您想如何初始化它。C++0x删除了此限制

请记住,这非常容易:

#include <boost/assign.hpp>
const foo::the_map foo::m = boost::assign::map_list_of(1, "a")(2, "b");
#包括
常量foo::映射foo::m=boost::赋值::映射列表(1,“a”)(2,“b”);

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

错误C2864:“MoveSequence::m”:在类中只能初始化静态常量整型数据成员*

因此,您希望在标题中包含以下内容:

class MoveSequence
{
    static std::map<StackIndex, std::string> _m_whatever;
};
类移动序列
{
静态std::map _m__,whatever;
};
然后在源(.cpp)文件中,您需要以下内容:

std::map<StackIndex, std::string> MoveSequence::_m_whatever( ..constructor args.. );
std::map MoveSequence::_m_which(…构造函数参数..);

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

错误C2864:“MoveSequence::m”:在类中只能初始化静态常量整型数据成员*

因此,您希望在标题中包含以下内容:

class MoveSequence
{
    static std::map<StackIndex, std::string> _m_whatever;
};
类移动序列
{
静态std::map _m__,whatever;
};
然后在源(.cpp)文件中,您需要以下内容:

std::map<StackIndex, std::string> MoveSequence::_m_whatever( ..constructor args.. );
std::map MoveSequence::_m_which(…构造函数参数..);

>P>正如其他人所建议的,您需要在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的构造函数调用它

哦,顺便说一句,枚举上不需要typedef:

enum StackIndex {
  ...
};

正如其他人所建议的,您需要在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的构造函数调用它

哦,顺便说一句,枚举上不需要typedef:

enum StackIndex {
  ...
};

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

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

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

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

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

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

我不知道,只是他头球中的那个(我猜)。我会换的。谢谢你,格曼!我在类中尝试了boost赋值,这就是导致错误的原因。在C++0x中找不到关于静态初始值设定项的信息,如果是静态的,哪个转换单元有存储?我在《我想可能
static const
有一个特例,但我也找不到。我不知道,他头上有什么(我猜)。我会换的。谢谢你,格曼!我在类中尝试了boost赋值,这就是导致错误的原因。在C++0x中找不到关于静态初始值设定项的信息,如果是静态的,哪个转换单元有存储?我在中看到过非静态成员,我想可能
static const
有一个特例,但我也找不到。谢谢Neil。我想通过boost::assign这件事,我试着少打字,因为我的枚举中大约有24个
StackIndex
s。Neil,为什么不
if(!m_map.empty())
?谢谢Neil。我想,对于boost::assign这件事,我试图减少键入,因为我的枚举中有大约24个
StackIndex
s。尼尔,如果(!m_map.empty())
,为什么不
if(!m_map.empty())
?太棒了。我真的很喜欢这个网站的所有新想法。然而,std::map和字符串数组在速度上有很大的区别吗?是的,字符串数组会快得多。如果StackIndex是连续的整数值(或者至少没有太多大的洞),那么数组肯定是最好的选择。我真的很喜欢这个网站的所有新想法。然而,std::map和字符串数组在速度上有很大的区别吗?是的,字符串数组会快得多。如果StackIndex是连续的整数值(或者至少没有太多的大洞),那么数组肯定是最好的选择。