Bonjour à tous,
Je dispose d'une classe de string template (composée d'un std::basic_string<T>), que j'ai jusqu'alors utilisée comme std::string, c'est à dire avec T = char (on va l'appeler str).
Cependant, j'ai récemment eu besoin d'utiliser des string unicode, donc T = unsigned int (on va l'appeler ustr).
Pour l'instant (je simplifie un peu), je n'ai qu'un constructeur :
Du coup, si je peux écrire ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 template<class T> class str_t { public : str_t(const T* array); // ... };
... ceci n'est pas possible :
Code : Sélectionner tout - Visualiser dans une fenêtre à part str s = "ma string";
... car "ma string" est un tableau de char, pas un tableau de uint.
Code : Sélectionner tout - Visualiser dans une fenêtre à part ustr s = "ma string";
Il me faudrait écrire :
J'aimerai pouvoir ajouter un constructeur à ma classe ustr pour qu'elle soit capable de faire la conversion implicitement.
Code : Sélectionner tout - Visualiser dans une fenêtre à part ustr s = UTF8ToUnicode("ma string");
Pour cela, je pourrais faire un copier coller de la classe str_t et la spécialiser pour T = uint, mais c'est sacrément moche (str_t est une classe assez énorme)...
Du coup j'ai eu une idée qui fait intervenir les traits :
Problème si T = char : il y a conflit entre les deux constructeurs.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 template<class T> class str_t { private : std::basic_string<T> s; public : str_t(const T* array) { s = array; } str_t(const char* array) { s = StringTraits<T>::Convert(array); } };
Je me suis donc dit que, si le compilateur (gcc) ne pouvait pas compiler le second constructeur (qui est de toute manière inutile pour T = char), alors il "l'oublierait" et se contenterai du premier.
J'ai donc écrit StringTraits de la sorte :
... et sa spécialisations :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 template<class T> class StringTraits { // Rien, pour provoquer une erreur de compilation. };
A ma grande surprise, le compilateur n'essaye même pas de compiler le second constructeur, et indique toujours qu'il y a un conflit...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 template<> class StringTraits<uint> { public : std::basic_string<uint> Convert(std::string s); };
Avez-vous une idée de comment je pourrais m'en sortir ?
Partager