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 :
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);
 
    // ...
};
Du coup, si je peux écrire ceci :
... ceci n'est pas possible :
... car "ma string" est un tableau de char, pas un tableau de uint.
Il me faudrait écrire :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
ustr s = UTF8ToUnicode("ma string");
J'aimerai pouvoir ajouter un constructeur à ma classe ustr pour qu'elle soit capable de faire la conversion implicitement.

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 :
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);
    }
};
Problème si T = char : il y a conflit entre les deux constructeurs.
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 :
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.
};
... et sa spécialisations :
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);
};
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...

Avez-vous une idée de comment je pourrais m'en sortir ?