30 votes

Surcharge d'une fonction C en fonction de la valeur de retour

Nous savons tous que vous pouvez surcharger une fonction selon les paramètres :

Pouvez-vous surcharger une fonction en fonction de la valeur de retour? Définissez une fonction qui retourne différentes choses en fonction de la façon dont la valeur de retour est utilisée :

Vous pouvez supposer que le premier paramètre se situe entre 0 et 9, pas besoin de vérifier l'entrée ou d'avoir une manipulation d'erreur.

44voto

paercebal Points 38526

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

34voto

Coincoin Points 12823
<pre><code></code><p>Non pas que je l'utiliserais.</p></pre>

22voto

Eclipse Points 27662

Si vous vouliez faire `` une vraie fonction au lieu d'une classe, vous pouvez simplement utiliser une classe intermédiaire:

Cela vous permet de faire des choses comme passer comme une fonction dans les `` algorithmes std:

19voto

MrZebra Points 6508

non.

Vous ne pouvez pas surcharger par la valeur de retour parce que l'appelant peut faire n'importe quoi (ou rien) avec elle. Considérer:

``

La valeur de retour est juste jeté, il n'y a donc aucun moyen qu'il pourrait choisir une surcharge basée sur la valeur de retour seul.

8voto

Pieter Points 9200

Utilisez la conversion implicite dans un entre les classes.

Vous avez l'idée, idée terrible si.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X