2009-07-14 8 views
5

C++ n'autorise pas le polymorphisme pour les méthodes basées sur leur type de retour. Cependant, en surchargeant une fonction de membre de conversion implicite, cela semble possible.Pourquoi les fonctions membres de conversion implicites surchargent-elles le travail par type de retour, alors qu'il n'est pas autorisé pour les fonctions normales?

Est-ce que quelqu'un sait pourquoi? Je pensais que les opérateurs sont manipulés comme des méthodes internes.

Edit: Voici un exemple:

struct func { 
    operator string() { return "1";} 
    operator int() { return 2; } 
}; 

int main() { 
    int x = func(); // calls int version 
    string y = func(); // calls string version 
    double d = func(); // calls int version 
    cout << func() << endl; // calls int version 
} 
+0

Pourriez-vous donner un exemple? Je ne suis pas sûr de ce que vous entendez par surcharge par type de retour. –

+0

Pourriez-vous donner un exemple? – jkeys

Répondre

11

Les opérateurs de conversion ne sont pas vraiment considérés comme des surcharges différentes et ils ne sont pas appelés en fonction de leur type de retour. Le compilateur ne les utilisera que lorsqu'il aura à (lorsque le type est incompatible et devrait être converti) ou lorsqu'il lui est explicitement demandé d'utiliser l'un d'entre eux avec un opérateur de conversion.

sémantiquement, ce que votre code est en train de faire est de déclarer plusieurs différents opérateurs de conversion de type et pas d'un seul surcharge opérateur.

+0

"Les opérateurs de conversion ne sont pas vraiment considérés comme des surcharges différentes". Ils ne sont pas du tout des fonctions surchargées: ils ont des noms différents. – curiousguy

3

Ce Retournons pas le type. C'est la conversion de type.

Considérons: func() crée un objet de type func. Il n'y a pas d'ambiguïté quant à la méthode (constructeur) qui sera invoquée.

La seule question qui reste est s'il est possible de le mouler aux types désirés. Vous avez fourni le compilateur avec la conversion appropriée, donc c'est heureux.

0

La résolution de surcharge choisit entre plusieurs fonctions candidates. Dans ce processus, le type de retour des candidats n'est effectivement pas pris en compte. Cependant, dans le cas des opérateurs de conversion, le "type de retour" est essentiel pour déterminer si cet opérateur est un candidat.

+0

Ces fonctions candidates ont différents types de retour et ** noms différents **. Ils ne sont pas surchargés, encore moins surchargés sur le type de retour. – curiousguy

+0

@curiousguy: Les fonctions de conversion peuvent être surchargées sur cv-qualification et template-ness. – MSalters

+0

Ceci est correct, mais dans cet exemple particulier, ils ne sont pas surchargés. – curiousguy

1

Il n'y a pas vraiment de raison technique pour éviter la surcharge des fonctions sur les types de résultat. Ceci est fait dans certains langages comme Ada par exemple, mais dans le contexte de C++ qui a aussi des conversions implicites (et deux sortes de conversions), l'utilité est réduite, et les interactions des deux fonctionnalités conduiraient rapidement à des ambiguïtés.

Notez que vous pouvez utiliser le fait que les conversions implicites sont définies par l'utilisateur pour simuler une surcharge du type de résultat:

class CallFProxy; 
CallFProxy f(int); 

class CallFProxy { 
    int myParameter; 
    CallFProxy(int i) : myParameter(i) {} 
public: 
    operator double() { std::cout << "Calling f(int)->double\n"; return myParameter; } 
    operator string() { std::cout << "Calling f(int)->string\n"; return "dummy"; } 
}; 
+0

"Il n'y a pas vraiment de raison technique pour éviter la surcharge des fonctions sur les types de résultats." La "raison technique" est qu'un appel de fonction a un type bien défini en C++ (et pas en Ada). Presque toutes les expressions en C++ ont un type et une signification bien définis, excepté (1) les sous-expressions sans signification dans un appel de fonction membre dans 'o.mf()', 'o.mf' n'est pas une sous-expression valide et fait ne pas avoir de type (si 'mf' est une fonction membre, pas un membre de données); (2) l'adresse d'une fonction surchargée, p.ex. '& std :: cos' (' cos (float) ',' cos (double) ', ...? – curiousguy

+0

(...) En C++, pour déterminer la signification d'une expression, vous pouvez commencer avec les sous-expressions internes, déterminer leur signification, et continuer tout le long (avec les exceptions que je viens de mentionner). Dans Ada, la signification de 'read()' peut dépendre du type de 'var' dans:' var: = read(); '. Notez que 'read();' n'est pas une instruction valide: il n'y a pas d'expression-instruction dans Ada. Vous devez soit appeler une procédure (** pas ** une fonction!), Soit faire une assignation. – curiousguy

Questions connexes