2010-01-11 9 views
0

J'ai un stackIndex défini comme enum suit:Comment initialiser une std :: map une fois pour qu'elle puisse être utilisée par tous les objets d'une classe?

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

J'ai créé une classe appelée MoveSequence, qui est une enveloppe pour un std::deque d'un bouquet de tuples de la forme <StackIndex, StackIndex>.

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

Je pensais que je pourrais créer un membre std::map statique de la classe MoveSequence, ce qui se traduirait par un StackIndex à un std::string, pour une utilisation par la fonction Print(). Mais quand j'ai essayé, je suis l'erreur:

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

Si ce ne est pas possible de créer un std :: carte en tant que membre statique, est-il une autre façon de créer un std :: carte qui se traduit par un StackIndex à un std::string qui peut être utilisé pour imprimer des objets MoveSequence?

merci

Beeband.

Répondre

3

Vous pouvez faire un std :: carte membre statique de la classe. Ce que vous ne pouvez pas faire est initiliaze dans la définition de la classe. Notez que c'est ce que l'erreur vous dit:

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

Donc, vous voulez avoir cela dans l'en-tête:

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

Et puis dans un fichier source (Cpp) que vous voulez ceci:

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

Vous devez déplacer l'initialisation dans un fichier source:

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

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

Avec cependant vous voulez initialiser. C++ 0x supprime cette restriction.

Gardez à l'esprit Boost.Assign rend cela très facile:

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

quelles sont ces itérations? –

+0

Je ne sais pas, juste ce qu'il avait dans sa tête (c'est-à-dire je devine). Je vais le changer. – GManNickG

+0

Merci GMan! J'ai essayé le boost assigner dans la classe, c'est ce qui m'a donné l'erreur. – BeeBand

1

Comme d'autres l'ont suggéré, vous devez créer une instance statique de la carte dans un fichier source C++. En ce qui concerne initialisant, je suggère de créer une fonction statique dans 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")); 
     } 
    } 
    ... 
}; 

Vous pouvez ensuite appeler cela du constructeur de MoveSequence.

Oh, et BTW il n'y a pas besoin pour le typedef sur le ENUM:

enum StackIndex { 
    ... 
}; 
+0

Merci Neil. Je suppose qu'avec la chose boost :: assign, j'essayais de ne pas trop taper, car j'ai environ 24 'StackIndex's dans mon énumération :). – BeeBand

+0

Neil, pourquoi pas 'if (! M_map.empty())'? – GManNickG

+0

@Gman - pourquoi pas, en effet - pure incompétence de ma part. –

1

Je ne pense pas que vous voulez un std :: carte (bien que toutes les autres réponses ici sont bons que comment faire ça). Il semble que vous vouliez simplement un tableau C statique de chaînes, où l'index est la valeur enum.

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

Ensuite stacknames [DECK] est "deck", etc.

+0

Brillant. J'aime vraiment ce site pour toutes les nouvelles idées. Cependant, y a-t-il une grande différence de vitesse entre une carte std :: map et un tableau de chaînes? – BeeBand

+0

Oui, un tableau de chaînes sera beaucoup plus rapide. –

+0

Si StackIndex est des valeurs entières consécutives (ou du moins ne contient pas trop de grands trous), un tableau est définitivement la solution. –