2017-05-13 1 views
7

Je cours, chacun d'entre eux retournent son nomEst-il prudent d'utiliser const char * literal comme une clé std :: map?

struct IFoo { 
    virtual const char * GetName() const = 0; 
} 

struct Foo : IFoo { 
    const char * GetName() const { return "Foo"; } 
} 

struct Bar: IFoo { 
    const char * GetName() const { return "Bar"; } 
} 

Et ailleurs:

Foo* a = new Foo(); 
Foo* b = new Foo(); 

std::map<const char *, int> data; 
data[a->GetName()] = 0; 
printf("%i", data[b->GetName()]); 

littéraux de chaîne doivent être stockés dans un endroit à la mémoire, mais est-ce 100%? Ce code fonctionne dans gcc, mais je ne suis pas sûr de son multi-plateforme.

+2

Oui ceci est sûr, en fait la disposition a été spécifiquement ajoutée à la norme C++ pour que cela fonctionne –

+1

Ceci est sûr, tant que vous appelez 'operator []' avec les résultats de 'GetName()'. Si vous essayez de l'appeler avec "Foo" 'codé en dur à partir d'une autre unité de traduction, le résultat n'est pas garanti. Sur 'gcc', cela fonctionnera car il fusionne des pools constants par défaut. – dasblinkenlight

+1

Très proche, presque un doublon: [Adresse littérale chaîne à travers les unités de traduction] (http://stackoverflow.com/q/26279628/335858) – dasblinkenlight

Répondre

5

Est-il possible d'utiliser const char * comme clé std::map?

Oui.

Cependant, considérer que ce n'est pas garanti pour trouver votre objet (mais peut, en fonction de la mise en œuvre):

data["Foo"] 

Et cela est garanti de ne pas trouver votre objet:

char[] str = "Foo"; 
data[str]; 

L'utilisation d'un comparateur de carte personnalisé basé sur std::strcmp permettrait aux deux cas ci-dessus de fonctionner.

Ensuite, le seul piège restant est la possibilité de stocker un pointeur vers un tampon local dans la carte qui survivrait au tampon local. Cela ne se produira pas si vous ne stockez que des littéraux de chaîne bien sûr, mais c'est quelque chose que vous devez garder à l'esprit lorsque vous travaillez avec la carte. Une clé std::string n'aurait pas une telle mise en garde.