Vous devez indiquer au compilateur de la version à utiliser. En C++, vous pouvez le faire de trois façons.
Explicitement différencier les appels en tapant
Vous avez un peu triché parce que vous avez envoyé un entier à une fonction d'attente pour un char, et à tort, envoyé au nombre de six lorsque le char de la valeur de '6' est pas 6 mais 54 (en ASCII):
std::string mul(char c, int n) { return std::string(n, c); }
std::string s = mul(6, 3); // s = "666"
La bonne solution serait, bien sûr,
std::string s = mul(static_cast<char>(54), 3); // s = "666"
C'était la peine de mentionner, je suppose, même si vous ne voulez pas la solution.
Explicitement différencier les appels par factice pointeur
Vous pouvez ajouter un paramètre fictif pour chacune des fonctions, donc forcer le compilateur à choisir le bon fonctionnement. Le plus simple est d'envoyer un NULL mannequin pointeur du type souhaité pour le retour:
int mul(int *, int i, int j) { return i*j; }
std::string mul(std::string *, char c, int n) { return std::string(n, c); }
Qui peut être utilisé avec le code:
int n = mul((int *) NULL, 6, 3); // n = 18
std::string s = mul((std::string *) NULL, 54, 3); // s = "666"
Explicitement différencier les appels par la création de modèles, la valeur de retour
Avec cette solution, nous allons créer une "dummy" de la fonction avec le code qui ne compile pas si instancié:
template<typename T>
T mul(int i, int j)
{
// If you get a compile error, it's because you did not use
// one of the authorized template specializations
const int k = 25 ; k = 36 ;
}
Notez que cette fonction ne compile pas, ce qui est une bonne chose, parce que nous voulons seulement d'utiliser certaines fonctions limitées par modèle de spécialisation:
template<>
int mul<int>(int i, int j)
{
return i * j ;
}
template<>
std::string mul<std::string>(int i, int j)
{
return std::string(j, static_cast<char>(i)) ;
}
Ainsi, le code suivant compile:
int n = mul<int>(6, 3); // n = 18
std::string s = mul<std::string>(54, 3); // s = "666"
Mais ce ne sera pas:
short n2 = mul<short>(6, 3); // error: assignment of read-only variable ‘k'
Explicitement différencier les appels par la création de modèles, la valeur de retour, 2
Hey, vous avez triché, trop!
Droit, j'ai fait d'utiliser les mêmes paramètres pour les deux "surchargé" des fonctions. Mais vous n'avez commencer la tricherie (voir ci-dessus)...
^_^
Plus sérieusement, si vous avez besoin d'avoir des paramètres différents, alors vous aurez à écrire plus de code, et ensuite utiliser explicitement le droit des types lors de l'appel de fonctions pour éviter les ambiguïtés:
// For "int, int" calls
template<typename T>
T mul(int i, int j)
{
// If you get a compile error, it's because you did not use
// one of the authorized template specializations
const int k = 25 ; k = 36 ;
}
template<>
int mul<int>(int i, int j)
{
return i * j ;
}
// For "char, int" calls
template<typename T>
T mul(char i, int j)
{
// If you get a compile error, it's because you did not use
// one of the authorized template specializations
const int k = 25 ; k = 36 ;
}
template<>
std::string mul<std::string>(char i, int j)
{
return std::string(j, (char) i) ;
}
Et ce code sera utilisé en tant que tel:
int n = mul<int>(6, 3); // n = 18
std::string s = mul<std::string>('6', 3); // s = "666"
Et la ligne suivante:
short n2 = mul<short>(6, 3); // n = 18
Ne serait toujours pas compiler.
Conclusion
J'aime le C++...
:-p