Dans les livres sur C++, pourquoi apprend-on à utiliser surcharge de fonction alors que nous avons templates à notre disposition en C++?
Ne serait-il pas préférable de montrer l'utilisation efficace (et correcte) des modèles? Par opposition à où la surcharge de fonctions est enseignée dans la plupart des livres sur C++?
Ou, y a-t-il de bonnes raisons d'utiliser l'un au lieu de l'autre?
Les modèles offrent un avantage lorsque vous souhaitez effectuer la même action sur des types qui peuvent être différents. Un exemple simple:
template <typename T>
T foo(const T& a, const T& b) { return a + b; }
Vous pouvez utiliser la surcharge lorsque vous souhaitez appliquer différentes opérations en fonction du type:
struct Foo{ void foo() const {} };
void foo(int i) { std::cout << "i = " << i << "\n"; }
void foo(const Foo& f) { f.foo(); }
Vous pouvez obtenir ce qui précède en utilisant des modèles et des spécialisations de modèles, mais ces spécialisations devraient représenter quelques exceptions au cas général.
Les modèles ne peuvent pas accepter un nombre variable d'arguments. Les surcharges peuvent. De plus, un modèle indique que vous pouvez opérer sur n'importe quel type de données, mais il est inutile de le représenter alors qu'en fait, la très grande majorité des modèles ne serait que des spécialisations (dans votre système). En outre, les surcharges peuvent être virtual
et les spécialisations de modèle ne le peuvent pas. Les spécialisations ne peuvent pas non plus différer dans leurs signatures de la base.
template<typename T> void foo(T& t);
template<> void foo<std::string>(std::string* ptr); // Illegal
void foo(std::string* ptr); // Legal
Cela limiterait considérablement les types de surcharge que vous pourriez produire par rapport au système actuel.
Vous utilisez généralement des modèles lorsque vous souhaitez effectuer le même ensemble d'opérations sur de nombreux types de données différents.
Vous utilisez généralement la surcharge de fonctions lorsque vous souhaitez effectuer différentes opérations sur certains ensembles de données.
l'avantage des modèles dans une situation où vous souhaitez effectuer le même ensemble d'opérations sur de nombreux types de données différents, est que le compilateur gérera pour vous au moment de la compilation tout nouveau type possible que vous pourrez créer à l'avenir en utilisant la fonction de modèle. si vous deviez utiliser la surcharge de fonctions, vous devez créer une nouvelle surcharge de fonctions à chaque fois que vous créez un nouveau type que vous souhaitez transmettre à la fonction spécifique.
Juste un ajout à la réponse de juanchopanza:
Avec les surcharges de fonctions, vous pouvez également faire varier le nombre d'arguments, ce qui peut être pratique.
Un exemple simple, si vous avez une fonction avec la déclaration suivante:
void foo(int i, int j);
Mais vous appelez souvent foo avec le premier argument 0, vous pouvez écrire la fonction suivante qui vous évite de taper.
void foo(int j) {
foo(0, j);
}
Les modèles (normalement) nécessitent que vous utilisiez la même syntaxe pour effectuer les opérations sur tous les types (pris en charge).
La surcharge de fonctions est (ou devrait être) utilisée de la même manière, mais vous permet d'utiliser la syntaxe différente pour effectuer les opérations pour différents types. C'est-à-dire que (même si vous n'êtes pas obligé de le faire), vous pouvez représenter les valeurs de différentes manières. Un exemple évident serait ce qu'on appelle atan
et atan2
dans la bibliothèque C. Avec atan
, on passe le rapport de la "montée à la" course, et on récupère l'angle que ce rapport représente. Avec atan2
nous transmettons les valeurs de l'augmentation et exécutons séparément (qui calcule à peu près le même résultat, mais comme on lui donne un peu plus de données d'entrée, cela peut aussi produire un résultat plus complet).
Bien que celles-ci soient implémentées en tant que fonctions entièrement distinctes en C, si elles étaient écrites en C++ depuis le début, il serait tout à fait approprié d'utiliser un seul nom (par exemple, atan
) surchargé pour un et deux paramètres:
double atan(double); // equivalent to current atan
double atan(double, double); // equivalent to current atan2
Les modèles (à l'exception de la spécialisation, qui remplace à peu près ce que les modèles eux-mêmes fournissent) ne prévoient pas de différences dans la syntaxe d'appel comme celle-ci.
La surcharge est également plus limitée - vous fournissez une surcharge pour chaque type spécifique que vous souhaitez prendre en charge (bien que si vous prenez un pointeur ou une référence, ceux-ci peuvent également prendre en charge les types dérivés). Avec les modèles, un seul modèle peut (au moins potentiellement) s'appliquer au type any.
Ainsi, overloading
et template
ont tous deux une utilisation égale.
une ligne difference
à leur sujet est:
overloading
est utilisé lorsque nous avons diverses fonctions, faisant des opérations SIMILAR
.
template
est utilisé lorsque nous avons diverses fonctions, faisant des opérations IDENTICAL
.
There is very big differnce between "SIMILAR" and "IDENTICAL".