2016-01-27 2 views
0

Je veux implémenter mon propre conteneur "simple" qui aura des propriétés de carte mais qui garde aussi l'ordre d'insertion. J'ai entendu parler de boost :: multi_index mais je trouve cela très difficile à comprendre pour ce que je veux.Comment faire ma "propre" carte sur gabarit?

Je fait une classe templated:

template<typename KEY, typename VALUE> 
class MyMap { 
    private : 
     std::vector<KEY> m_keys; 
     std::vector<VALUE> m_values; 

    public : 
     void insert(KEY& key, VALUE& val) { 
      //Test if key exists // 
      m_keys.push_back(key); 
      m_values.push_back(val); 
     } 

     /* Other methods like erase/size/operator[]/begin/etc. */ 

}; 

Juste pour le tester, je voulais faire quelque chose comme ceci:

int main() { 
    MyMap<string,int> m; 
    m.insert("test",1); 
    m.insert("cat",2); 

    for(auto& item : m) { 
     cout << item << endl; 
     cout << m[item] << endl; 
    } 
} 

Mais je continue à obtenir une erreur de compilation sur les inserts (et [ ]) car il traduit ma clé dans une chaîne de base et non une chaîne. Cela me rend fou et je ne trouve aucune réponse (ou aucun mot pour décrire correctement mon problème à la recherche d'une réponse). Je suppose que cela a quelque chose à voir avec les allocateurs, mais je n'arrive pas à comprendre comment y remédier. Comment faire pour que ma carte fasse cette conversion mais reste aussi générale car j'en aurai besoin avec d'autres classes (propres)? Après avoir résolu le problème "chaîne", j'ai eu des problèmes lors du passage int, car il attendait & int. Suivi kebs conseil et implémenté un vecteur> à la place et s'est débarrassé des problèmes de conversion ... :)

+0

Toute raison pour laquelle vous ne pas utiliser le conteneur fourni par la bibliothèque standard? – kebs

+0

@kebs: Oui, je veux garder l'ordre d'insertion car j'en aurai besoin plus tard, mais je dois aussi associer une classe à une clé unique :) – Holywa

+0

Je ne suis pas sûr que ce soit la meilleure façon d'y aller. Vous pouvez aussi stocker dans un 'std :: vector' quelque' std :: pair '(sauf si vous avez besoin d'y accéder via la clé). Mais d'un point de vue général, je pense que les situations où la bibliothèque standard ne rentre pas sont très rares ... – kebs

Répondre

0

Vous ne pouvez pas construire une référence à partir d'un const char* (même si elle est moulée en une chaîne), essayez ceci à la place:

template<typename KEY, typename VALUE> 
    void insert(KEY key, VALUE val) { 
     m_keys.push_back(key); 
     m_values.push_back(val); 
    } 

Plus précisément, le compilateur est assez clair sur le problème:

error: invalid initialization of non-const reference of type 'std::basic_string&' from an rvalue of type 'std::basic_string' m.insert("test",1);

+0

Mais là, je vais passer des arguments par des valeurs et non par référence? Cette classe est également destinée à stocker des classes entières alors j'essayais d'éviter ça! – Holywa

+0

De toute façon, 'vector :: push_back()' fera une copie. Et la valeur initiale est passée, bien qu'il semble créer une copie, il sera optimisé par le compilateur. – kebs

+0

Je n'ai pas eu l'erreur de compilation que vous avez édité en :) J'ai oublié que push_back() a fait une copie, merci :) – Holywa