Archives mensuelles pour mai 2011

Utiliser une chaîne de caractère comme paramètre template C++

Le jeu repose sur une machine à état où les différents états sont identifiés par une chaîne de caractère (« Options », »Menu », »Scores » etc…). Je passais ce nom via le constructeur de la class parente ( par exemple

 COptionsState() : IGameState("Options") { } 

). Pour certaines raisons (pour le fun aussi), j’ai voulu passer ce paramètre non plus au runtime mais à la compilation via un paramètre template type template <const char* ID> class IGameState {}. J’ai alors – naïvement tenté – de faire dériver l’état des options de la classe template IGameState précédente comme suit:

class COptionsState() : public IGameState<"Options"> { ... }

Avec les erreurs qui vont bien. Ceci n’est pas possible car la variable passée en paramètre doit être linké de manière  externe et non locale et ce pour s’assurer que 2 classes distinctes ne seront pas définies à partir du même template pour le même paramètre.

On doit donc déclarer une variable linkable de manière externe. Pour ceci on peut utiliser le mot clé « extern » => extern const char* Options_Str = « options »; et définir ainsi

class COptionsState() : public IGameState<Options_Str> { ... }

. Aussi apparemment il existe une différence entre const char* Str considérée comme une variable et non comme une adresse mémoire par gcc quand passée en argument. Ainsi il vaut mieux définir Options_Str sous forme de tableau:

 extern const char Options_Str[] = "options";

qui chez moi (mingw) a fait disparaitre tous les messages d’erreurs.

Note: Boost MPL a ajouté desoptions pour les strings apparemment.

Autre lien intéressant sur le sujet, la FAQ comeau