Que fait l'opérateur unaire plus? Il y a plusieurs définitions que j'ai trouvées ( ici et ici ) mais je n'ai toujours aucune idée de ce à quoi cela servirait. Il semble que cela ne fasse rien, mais il y a une raison à cela, non?
Il est là pour être surchargé si vous en ressentez le besoin; pour tous les types prédéfinis, il s'agit essentiellement d'un no-op.
Les utilisations pratiques d'un opérateur arithmétique unaire sans opération sont assez limitées et ont tendance à se rapporter aux conséquences de l'utilisation d'une valeur dans une expression arithmétique, plutôt qu'à l'opérateur lui-même. Par exemple, il peut être utilisé pour forcer l'élargissement de types intégraux plus petits à int
, ou pour garantir que le résultat d'une expression est traité comme une valeur r et donc non compatible avec un paramètre de référence nonconst
. Je soutiens, cependant, que ces utilisations conviennent mieux au code golf qu'à la lisibilité. :-)
En fait, unaire plus fait quelque chose - même en C. Il effectue les conversions arithmétiques habituelles sur l'opérande et renvoie une nouvelle valeur, qui peut être un entier de plus grande largeur. Si la valeur d'origine était un entier non signé de largeur inférieure à int
, elle sera également remplacée par une valeur signed
.
Habituellement, ce n'est pas si important, mais cela peut avoir un effet, donc ce n'est pas une bonne idée d'utiliser unaire plus comme une sorte de "commentaire" indiquant qu'un entier est positif. Considérez le programme C++ suivant:
void foo(unsigned short x)
{
std::cout << "x is an unsigned short" << std::endl;
}
void foo(int x)
{
std::cout << "x is an int" << std::endl;
}
int main()
{
unsigned short x = 5;
foo(+x);
}
Cela affichera "x est un int".
Ainsi, dans cet exemple, unary plus a créé une nouvelle valeur avec un type différent et signness.
De la deuxième édition de K&R:
L'unaire + est nouveau avec la norme ANSI. Il a été ajouté par symétrie avec l'unaire -.
Je l'ai vu utilisé pour plus de clarté, pour souligner la valeur positive par opposition à une valeur négative:
shift(+1);
shift(-1);
Mais c'est une utilisation assez faible. La réponse est certainement une surcharge.
Une chose que l'unaire intégré +
do transforme lvalue en rvalue. Par exemple, vous pouvez le faire
int x;
&x;
mais tu ne peux pas faire ça
&+x;
:)
P.S. La "surcharge" n'est certainement pas la bonne réponse. Unaire +
a été hérité de C et il n'y a pas de surcharge d'opérateur au niveau utilisateur en C.
La principale chose qu'unary + accomplit est la promotion de type vers un int pour les types de données plus petits qu'int. Cela peut être très utile si vous essayez d'imprimer des données de caractères à l'aide de std::cout
sous forme de données numériques.
char x = 5;
std::cout << +x << "\n";
est très différent de
char x=5;
std::cout << x << "\n";
Il est également disponible pour la surcharge, mais en pratique, votre surcharge devrait être presque un NOP.
Si vous avez besoin d'imprimer la valeur numérique d'octets bruts (par exemple, de petits nombres stockés en tant que char) pour le débogage ou pour une raison quelconque, unary + peut simplifier le code d'impression. Considérer
char c = 42;
cout << c << endl; // prints "*\n", not what you want in this case
cout << (int)c << endl; // prints "42\n", ok
cout << +c << endl; // prints "42\n", much easier to type
Ceci n'est qu'un exemple rapide. Je suis sûr qu'il y a d'autres moments où unary + peut aider à traiter vos octets plus comme des nombres plutôt que comme du texte.
Une friandise historique. Le comité de normalisation C99 a également estimé que les utilisations existantes de unary plus étaient assez rares, comme en témoigne leur considération de le réutiliser pour obtenir une autre caractéristique du langage: l'inhibition de l'évaluation du temps de traduction des expressions constantes à virgule flottante. Voir la citation suivante de la justification C, section F.7.4:
Une première version de cette spécification permettait l'arithmétique des constantes de temps de traduction, mais permettait à l'opérateur unaire +, lorsqu'il était appliqué à un opérande, d'inhiber l'évaluation du temps de traduction des expressions constantes.
En fin de compte, la sémantique a été inversée, l'évaluation au moment de l'exécution étant appliquée dans la plupart des contextes (au moins jusqu'à la règle "comme si"), et la possibilité d'appliquer l'évaluation au moment de la traduction en utilisant des initialiseurs statiques. Notez que la principale différence réside dans l'occurrence d'exceptions à virgule flottante et d'autres paramètres d'arrondi ou de précision à virgule flottante, le cas échéant.
Unary plus était présent en C, où il ne faisait absolument rien (un peu comme le mot clé auto
). Pour ne pas l'avoir, Stroustrup aurait dû introduire une incompatibilité gratuite avec C.
Une fois qu'il était en C++, il était naturel d'autoriser une fonction de surcharge, tout comme unus moins, et Stroustrup aurait pu l'introduire pour cette raison s'il n'était pas déjà là.
Donc ça ne veut rien dire. Il peut être utilisé comme une sorte de décoration pour rendre les choses plus symétriques, en utilisant +1,5 à l'opposé de -1,5 par exemple. En C++, il peut être surchargé, mais cela va être déroutant si operator+()
fait quelque chose. N'oubliez pas la règle standard: lors de la surcharge d'opérateurs arithmétiques, faites des choses comme le font les int
s.
Si vous cherchez une raison pour laquelle il est là, trouvez quelque chose sur les débuts de C. Je soupçonne qu'il n'y avait pas de bonne raison, car C n'était pas vraiment conçu. Considérez le mot-clé auto
inutile (vraisemblablement contrairement à static
, qui est maintenant recyclé en C++ 0x), et le mot-clé entry
, qui n'a jamais rien fait (et plus tard omis en C90). Il y a un célèbre e-mail dans lequel Ritchie ou Kernighan disent que, lorsqu'ils ont réalisé que la priorité des opérateurs avait des problèmes, il y avait déjà trois installations avec des milliers de lignes de code qu'ils ne voulaient pas casser.
Pas tant. L'argument général pour autoriser la surcharge de operator+()
est qu'il existe certainement des utilisations réelles pour surcharger operator-()
, et ce serait très bizarre (ou asymétrique) si vous deviez autoriser la surcharge operator-()
mais pas operator+()
.
Je crois que j'ai lu cet argument de Stroustrop pour la première fois, mais je n'ai pas mes livres avec moi pour le vérifier. Je peux me tromper.
Je ne peux citer aucune source pour cela, mais j'ai compris que c'est pour une promotion de type explicite, ce qui implique une conversion de type sans perte. Cela le place en haut de la hiérarchie de conversion,
new_type operator+(old_type)
new_type(old_type)
operator(new_type)(old_type)
new_type operator=(old_type)
Bien sûr, cela vient de mon interprétation d'une note dans l'un des manuels Microsoft (vraiment anciens) c/c ++ que j'ai lu il y a environ 15 ans, alors prenez-le avec un grain de sel.
#include <stdio.h>
int main()
{
unsigned short x = 5;
printf ("%d\n",sizeof(+x));
printf ("%d\n",sizeof(x));
return 0;
}
Comme le montre l'exemple ci-dessus, l'unaire + change vraiment le type, la taille 4 et 2 respectivement. Bizarre que l'expression + x soit en effet calculée dans la taille de, je pensais que ce n'était pas censé le faire. C'est peut-être dû au fait que sizeof a la même priorité que l'unary +.
Je suppose que vous pouvez l'utiliser pour toujours rendre un nombre positif. Il suffit de surcharger l'opérateur unaire + pour qu'il soit abs. Cela ne vaut pas vraiment la peine de confondre vos collègues développeurs, sauf si vous voulez vraiment simplement obscurcir votre code. Alors ça marcherait bien.