Arithmetic operators
Retourne le résultat d'une opération arithmétique spécifique.
| Nom de l'opérateur | Syntaxe | Exemples de prototypes (pour class T ) | ||
|---|---|---|---|---|
| Définition à l'intérieur de la classe | Définition à l'extérieur de la classe | |||
| Plus unaire | + a | T T :: operator + ( ) const ; | T operator + ( const T & a ) ; | |
| Moins unaire | - a | T T :: operator - ( ) const ; | T operator - ( const T & a ) ; | |
| Addition | a + b | T T :: operator + ( const T2 & b ) const ; | T operator + ( const T & a, const T2 & b ) ; | |
| Soustraction | a - b | T T :: operator - ( const T2 & b ) const ; | T operator - ( const T & a, const T2 & b ) ; | |
| Multiplication | a * b | T T :: operator * ( const T2 & b ) const ; | T operator * ( const T & a, const T2 & b ) ; | |
| Division | a / b | T T :: operator / ( const T2 & b ) const ; | T operator / ( const T & a, const T2 & b ) ; | |
| Reste | a % b | T T :: operator % ( const T2 & b ) const ; | T operator % ( const T & a, const T2 & b ) ; | |
| NOT binaire | ~a | T T :: operator ~ ( ) const ; | T operator~ ( const T & a ) ; | |
| ET bit à bit | a & b | T T :: operator & ( const T2 & b ) const ; | T operator & ( const T & a, const T2 & b ) ; | |
| OU au niveau des bits | a | b | T T :: operator | ( const T2 & b ) const ; | T operator | ( const T & a, const T2 & b ) ; | |
| OU exclusif au niveau des bits | a ^ b | T T :: operator ^ ( const T2 & b ) const ; | T operator ^ ( const T & a, const T2 & b ) ; | |
| Décalage à gauche au niveau du bit | a << b | T T :: operator << ( const T2 & b ) const ; | T operator << ( const T & a, const T2 & b ) ; | |
| Décalage à droite binaire | a >> b | T T :: operator >> ( const T2 & b ) const ; | T operator >> ( const T & a, const T2 & b ) ; | |
|
||||
Table des matières |
Explication générale
Tous les opérateurs arithmétiques intégrés calculent le résultat d'une opération arithmétique spécifique et retournent son résultat. Les arguments ne sont pas modifiés.
Conversions
Si l'opérande passé à un opérateur arithmétique intégré est de type intégral ou de type énumération non-scopée, alors avant toute autre action (mais après la conversion lvalue-vers-rvalue, si applicable), l'opérande subit la promotion intégrale . Si un opérande a un type tableau ou fonction, la conversion tableau-vers-pointeur et la conversion fonction-vers-pointeur sont appliquées.
Pour les opérateurs binaires (sauf les décalages), si les opérandes promus ont des types différents, les conversions arithmétiques usuelles sont appliquées.
Dépassements
L'arithmétique des entiers non signés est toujours effectuée
modulo 2
n
où n est le nombre de bits dans cet entier particulier. Par exemple, pour
unsigned
int
, ajouter un à
UINT_MAX
donne
0
, et soustraire un de
0
donne
UINT_MAX
.
Lorsqu'une opération arithmétique sur des entiers signés dépasse la capacité (le résultat ne tient pas dans le type de résultat), le comportement est indéfini — les manifestations possibles d'une telle opération incluent :
- il boucle selon les règles de la représentation (généralement le complément à deux ),
-
il génère un piège — sur certaines plateformes ou via des options de compilation (par exemple
-ftrapvdans GCC et Clang), - il sature à la valeur minimale ou maximale (sur de nombreux DSP),
- il est complètement optimisé par le compilateur .
Environnement de virgule flottante
Si
#pragma STDC FENV_ACCESS
est pris en charge et défini sur
ON
, tous les opérateurs arithmétiques à virgule flottante respectent la
direction d'arrondi
actuelle et signalent les erreurs arithmétiques à virgule flottante comme spécifié dans
math_errhandling
, sauf s'ils font partie d'un
initialiseur statique
(auquel cas les exceptions à virgule flottante ne sont pas levées et le mode d'arrondi est vers le plus proche).
Contraction en virgule flottante
Sauf si
#pragma STDC FP_CONTRACT
est pris en charge et défini sur
OFF
, tous les calculs en virgule flottante peuvent être effectués comme si les résultats intermédiaires avaient une plage et une précision infinies, c'est-à-dire que les optimisations qui omettent les erreurs d'arrondi et les exceptions en virgule flottante sont autorisées. Par exemple, le C++ permet l'implémentation de
(
x
*
y
)
+
z
avec une seule instruction CPU de multiplication-addition fusionnée ou l'optimisation de
a
=
x
*
x
*
x
*
x
;
en
tmp
=
x
*
x
;
a
=
tmp
*
tmp
.
Sans rapport avec la contraction, les résultats intermédiaires de l'arithmétique en virgule flottante peuvent avoir une plage et une précision différentes de celles indiquées par leur type, voir FLT_EVAL_METHOD .
Formellement, la norme C++ ne fournit aucune garantie sur la précision des opérations en virgule flottante.
Opérateurs arithmétiques unaires
Les expressions d'opérateurs arithmétiques unaires ont la forme
+
expression
|
(1) | ||||||||
-
expression
|
(2) | ||||||||
Les opérateurs unaires
+
et
-
ont une
précédence
plus élevée que tous les opérateurs arithmétiques binaires, donc
l'expression
ne peut pas contenir d'opérateurs arithmétiques binaires de premier niveau. Ces opérateurs s'associent de droite à gauche :
+a - b; // équivalent à (+a) - b, PAS à +(a - b) -c + d; // équivalent à (-c) + d, PAS à -(c + d) +-e; // équivalent à +(-e), l'opérateur unaire + est une opération nulle si « e » est un type natif // car toute promotion possible est effectuée lors de la négation
Opérateurs arithmétiques unaires intégrés
-a , où N est le nombre de bits après promotion.
- En d'autres termes, le résultat est le complément à deux de l'opérande (où l'opérande et le résultat sont considérés comme non signés).
Surcharges
Dans la
résolution de surcharge pour les opérateurs définis par l'utilisateur
, pour chaque type arithmétique promu sans qualificatif cv
A
et pour chaque type
T
, les signatures de fonctions suivantes participent à la résolution de surcharge :
|
A operator
+
(
A
)
|
||
|
T
*
operator
+
(
T
*
)
|
||
|
A operator
-
(
A
)
|
||
#include <iostream> int main() { char c = 0x6a; int n1 = 1; unsigned char n2 = 1; unsigned int n3 = 1; std::cout << "char: " << c << " int: " << +c << "\n" "-1, where 1 is signed: " << -n1 << "\n" "-1, where 1 is unsigned char: " << -n2 << "\n" "-1, where 1 is unsigned int: " << -n3 << '\n'; char a[3]; std::cout << "size of array: " << sizeof a << "\n" "size of pointer: " << sizeof +a << '\n'; }
Sortie possible :
char: j int: 106 -1, where 1 is signed: -1 -1, where 1 is unsigned char: -1 -1, where 1 is unsigned int: 4294967295 size of array: 3 size of pointer: 8
Opérateurs additifs
Les expressions d'opérateur additif ont la forme
lhs
+
rhs
|
(1) | ||||||||
lhs
-
rhs
|
(2) | ||||||||
Les opérateurs binaires
+
et
-
ont une
précédence
plus élevée que tous les autres opérateurs arithmétiques binaires, à l'exception de
*
,
/
et
%
. Ces opérateurs s'associent de gauche à droite :
a + b * c; // équivalent à a + (b * c), PAS (a + b) * c d / e - f; // équivalent à (d / e) - f, PAS d / (e - f) g + h >> i; // équivalent à (g + h) >> i, PAS g + (h >> i) j - k + l - m; // équivalent à ((j - k) + l) - m
Opérateurs additifs intégrés
Pour les opérateurs binaires plus et moins intégrés, les deux lhs et rhs doivent être des prvalues, et l'une des conditions suivantes doit être satisfaite :
- Les deux opérandes sont de type arithmétique ou énumération non délimitée. Dans ce cas, les conversions arithmétiques usuelles sont appliquées aux deux opérandes.
- Exactement un opérande est de type entier ou énumération non délimitée. Dans ce cas, la promotion entière est appliquée à cet opérande.
Dans la description restante de cette section, « opérande(s) », lhs et rhs font référence aux opérande(s) converti(s) ou promu(s).
- Les deux opérandes ont un type arithmétique. Dans ce cas, le résultat est la somme des opérandes.
- Un opérande est un pointeur vers un type d'objet complètement défini, et l'autre opérande a un type entier. Dans ce cas, la valeur entière est ajoutée au pointeur (voir pointer arithmetic ).
- Les deux opérandes ont un type arithmétique. Dans ce cas, le résultat est la différence résultant de la soustraction de rhs à lhs .
- lhs est un pointeur vers un type d'objet complètement défini, et rhs a un type entier. Dans ce cas, la valeur entière est soustraite du pointeur (voir arithmétique des pointeurs ).
- Les deux opérandes sont des pointeurs vers des versions qualifiées cv ou non qualifiées cv du même type d'objet complètement défini. Dans ce cas rhs est soustrait de lhs (voir arithmétique des pointeurs ).
Si les deux opérandes ont un type à virgule flottante, et que le type prend en charge l'arithmétique à virgule flottante IEEE (voir std::numeric_limits::is_iec559 ):
- Si un opérande est NaN, le résultat est NaN.
- L'infini moins l'infini est NaN, et FE_INVALID est déclenché.
- L'infini plus l'infini négatif est NaN, et FE_INVALID est déclenché.
Arithmétique des pointeurs
Lorsqu'une expression J de type intégral est ajoutée ou soustraite d'une expression P de type pointeur, le résultat a le type de P .
- Si P évalue à une valeur de pointeur nul et J évalue à 0 , le résultat est une valeur de pointeur nul.
-
Sinon, si
P
pointe vers le
ième élément d'un objet tableau x avec n éléments, étant donné la valeur de J comme j , P est ajouté ou soustrait comme suit :
-
- Les expressions P + J et J + P
-
-
pointent vers le
i+jème élément de x si i + j est dans[ 0 ,n), et - sont des pointeurs après la fin du dernier élément de x si i + j est n .
-
pointent vers le
- L'expression P - J
-
-
pointe vers le
i-jème élément de x si i - j est dans[ 0 ,n), et - est un pointeur après la fin du dernier élément de x si i - j est n .
-
pointe vers le
- Les autres valeurs de j entraînent un comportement indéfini.
- Sinon, si P pointe vers un objet complet, un sous-objet de classe de base ou un sous-objet membre y , étant donné la valeur de J comme j , P est ajouté ou soustrait comme suit :
-
- Les expressions P + J et J + P
-
- pointent vers y si j est 0 , et
- sont des pointeurs au-delà de la fin de y si j est 1 .
- L'expression P - J
-
- pointe vers y si j est 0 , et
- est un pointeur au-delà de la fin de y si j est - 1 .
- Les autres valeurs de j entraînent un comportement indéfini.
- Sinon, si P est un pointeur au-delà de la fin d'un objet z , étant donné la valeur de J comme j :
-
- Si z est un objet tableau avec n éléments, P est ajouté ou soustrait comme suit :
-
- Les expressions P + J et J + P
-
-
pointent vers le
n+jième élément de z si n + j est dans[ 0 ,n), et - sont des pointeurs après la fin du dernier élément de z si j est 0 .
-
pointent vers le
- L'expression P - J
-
-
pointe vers le
n-jième élément de z si n - j est dans[ 0 ,n), et - est un pointeur après la fin du dernier élément de z si j est 0 .
-
pointe vers le
- Les autres valeurs de j entraînent un comportement indéfini.
- Sinon, P est ajouté ou soustrait comme suit :
-
- Les expressions P + J et J + P
-
- pointent vers z si j est - 1 , et
- sont des pointeurs après la fin de z si j est 0 .
- L'expression P - J
-
- pointe vers z si j est 1 , et
- est un pointeur après la fin de z si j est 0 .
- Les autres valeurs de j entraînent un comportement indéfini.
- Sinon, le comportement n'est pas défini.
Lorsque deux expressions de pointeur P et Q sont soustraites, le type du résultat est std::ptrdiff_t .
- Si P et Q évaluent tous deux à des valeurs de pointeur nul , le résultat est 0 .
-
Sinon, si
P
et
Q
pointent respectivement vers le
i-ième et lej-ième élément du même tableau x , l'expression P - Q a pour valeur i − j .
-
- Si i − j n'est pas représentable par std::ptrdiff_t , le comportement est indéfini.
- Sinon, si P et Q pointent vers le même objet complet, sous-objet de classe de base ou sous-objet membre, le résultat est 0 .
- Sinon, le comportement est indéfini.
Ces opérateurs arithmétiques de pointeur permettent aux pointeurs de satisfaire les LegacyRandomAccessIterator requirements.
Pour l'addition et la soustraction, si
P
ou
Q
ont le type « pointeur vers
T
(éventuellement qualifié cv) », où
T
et le type d'élément du tableau ne sont pas
similaires
, le comportement est indéfini :
int arr[5] = {1, 2, 3, 4, 5}; unsigned int *p = reinterpret_cast<unsigned int*>(arr + 1); unsigned int k = *p; // OK, la valeur de « k » est 2 unsigned int *q = p + 1; // comportement indéfini : « p » pointe vers int, pas unsigned int
Surcharges
Dans la
résolution de surcharge pour les opérateurs définis par l'utilisateur
, pour chaque paire de types arithmétiques promus
L
et
R
et pour chaque type objet
T
, les signatures de fonctions suivantes participent à la résolution de surcharge :
|
LR opérateur
+
(
L, R
)
|
||
|
LR opérateur
-
(
L, R
)
|
||
|
T
*
opérateur
+
(
T
*
,
std::
ptrdiff_t
)
|
||
|
T
*
opérateur
+
(
std::
ptrdiff_t
, T
*
)
|
||
|
T
*
opérateur
-
(
T
*
,
std::
ptrdiff_t
)
|
||
|
std::
ptrdiff_t
opérateur
-
(
T
*
, T
*
)
|
||
où
LR
est le résultat des
conversions arithmétiques habituelles
appliquées à
L
et
R
.
#include <iostream> int main() { char c = 2; unsigned int un = 2; int n = -10; std::cout << " 2 + (-10), where 2 is a char = " << c + n << "\n" " 2 + (-10), where 2 is unsigned = " << un + n << "\n" " -10 - 2.12 = " << n - 2.12 << '\n'; char a[4] = {'a', 'b', 'c', 'd'}; char* p = &a[1]; std::cout << "Pointer addition examples: " << *p << *(p + 2) << *(2 + p) << *(p - 1) << '\n'; char* p2 = &a[4]; std::cout << "Pointer difference: " << p2 - p << '\n'; }
Sortie :
2 + (-10), where 2 is a char = -8 2 + (-10), where 2 is unsigned = 4294967288 -10 - 2.12 = -12.12 Pointer addition examples: bdda Pointer difference: 3
Opérateurs multiplicatifs
Les expressions d'opérateur multiplicatif ont la forme
lhs
*
rhs
|
(1) | ||||||||
lhs
/
rhs
|
(2) | ||||||||
lhs
%
rhs
|
(3) | ||||||||
Les opérateurs multiplicatifs ont une précédence plus élevée que tous les autres opérateurs arithmétiques binaires. Ces opérateurs s'associent de gauche à droite :
a + b * c; // équivalent à a + (b * c), PAS (a + b) * c d / e - f; // équivalent à (d / e) - f, PAS d / (e - f) g % h >> i; // équivalent à (g % h) >> i, PAS g % (h >> i) j * k / l % m; // équivalent à ((j * k) / l) % m
Opérateurs multiplicatifs intégrés
Pour les opérateurs de multiplication et de division intégrés, les deux opérandes doivent être de type arithmétique ou d'énumération non délimitée. Pour l'opérateur de reste intégré, les deux opérandes doivent être de type intégral ou d'énumération non délimitée. Conversions arithmétiques usuelles sont effectuées sur les deux opérandes.
Dans la description restante de cette section, « opérande(s) », lhs et rhs font référence aux opérande(s) converti(s).
- La multiplication d'un NaN par n'importe quel nombre donne NaN.
- La multiplication de l'infini par zéro donne NaN et FE_INVALID est déclenché.
- Si un opérande est NaN, le résultat est NaN.
- Diviser un nombre non nul par ±0.0 donne l'infini avec le signe correct et FE_DIVBYZERO est déclenché.
- Diviser 0.0 par 0.0 donne NaN et FE_INVALID est déclenché.
Note : Jusqu'à ce que CWG issue 614 soit résolue ( N2757 ), si un ou deux opérandes de l'opérateur binaire % étaient négatifs, le signe du reste était défini par l'implémentation, car il dépend de la direction d'arrondi de la division entière. La fonction std::div fournissait un comportement bien défini dans ce cas.
Remarque : pour le reste en virgule flottante, voir std::remainder et std::fmod .
Surcharges
Dans la
résolution de surcharge pour les opérateurs définis par l'utilisateur
, pour chaque paire de types arithmétiques promus
LA
et
RA
et pour chaque paire de types entiers promus
LI
et
RI
, les signatures de fonctions suivantes participent à la résolution de surcharge :
|
LRA operator
*
(
LA, RA
)
|
||
|
LRA operator
/
(
LA, RA
)
|
||
|
LRI operator
%
(
LI, RI
)
|
||
où
LRx
est le résultat des
conversions arithmétiques usuelles
appliquées à
Lx
et
Rx
.
#include <iostream> int main() { char c = 2; unsigned int un = 2; int n = -10; std::cout << "2 * (-10), where 2 is a char = " << c * n << "\n" "2 * (-10), where 2 is unsigned = " << un * n << "\n" "-10 / 2.12 = " << n / 2.12 << "\n" "-10 / 21 = " << n / 21 << "\n" "-10 % 21 = " << n % 21 << '\n'; }
Sortie :
2 * (-10), where 2 is a char = -20 2 * (-10), where 2 is unsigned = 4294967276 -10 / 2.12 = -4.71698 -10 / 21 = 0 -10 % 21 = -10
Opérateurs logiques bit à bit
Les expressions d'opérateurs logiques bit à bit ont la forme
~
rhs
|
(1) | ||||||||
lhs
&
rhs
|
(2) | ||||||||
lhs
|
rhs
|
(3) | ||||||||
lhs
^
rhs
|
(4) | ||||||||
`. Les termes `lhs` et `rhs` sont des termes spécifiques au C++ (left-hand side/right-hand side) et ne doivent pas être traduits selon les instructions. Les numéros (1) à (4) sont des identifiants et restent inchangés. Aucune traduction n'était donc nécessaire dans ce cas précis.
L'opérateur de négation bit à bit a une précédence plus élevée que tous les opérateurs arithmétiques binaires. Il s'associe de droite à gauche :
~a - b; // équivalent à (~a) - b, PAS ~(a - b) ~c * d; // équivalent à (~c) * d, PAS ~(c * d) ~-e; // équivalent à ~(-e)
Il existe une ambiguïté dans la grammaire lorsque
~
est suivi d'un
nom de type
ou d'un spécificateur
decltype
(depuis C++11)
: il peut s'agir soit de l'opérateur~, soit du début d'un identifiant de
destructeur
). L'ambiguïté est résolue en traitant
~
comme opérateur~.
~
ne peut commencer un identifiant de destructeur qu'aux endroits où la formation d'un opérateur~ est syntaxiquement invalide.
Tous les autres opérateurs logiques bit à bit ont une précédence inférieure à tous les autres opérateurs arithmétiques binaires. Le ET bit à bit a une précédence supérieure au OU exclusif bit à bit, qui a une précédence supérieure au OU bit à bit. Ils s'associent de gauche à droite :
a & b * c; // équivalent à a & (b * c), PAS (a & b) * c d / e ^ f; // équivalent à (d / e) ^ f, PAS d / (e ^ f) g << h | i; // équivalent à (g << h) | i, PAS g << (h | i) j & k & l; // équivalent à (j & k) & l m | n ^ o // équivalent à m | (n ^ o)
Opérateurs logiques bit à bit intégrés
Pour l'opérateur de négation bit à bit intégré, rhs doit être une prvalue de type entier ou énumération non délimitée, et une promotion entière est effectuée sur rhs . Pour les autres opérateurs logiques bit à bit intégrés, les deux opérandes doivent avoir un type entier ou énumération non délimitée, et les conversions arithmétiques usuelles sont effectuées sur les deux opérandes.
Dans la description restante de cette section, « opérande(s) », lhs et rhs font référence aux opérande(s) converti(s) ou promu(s).
- Autrement dit, le résultat est le complément à un de l'opérande (où l'opérande et le résultat sont considérés comme non signés).
Surcharges
Dans la
résolution de surcharge pour les opérateurs définis par l'utilisateur
, pour chaque paire de types entiers promus
L
et
R
, les signatures de fonctions suivantes participent à la résolution de surcharge :
|
R operator~
(
R
)
|
||
|
LR operator
&
(
L, R
)
|
||
|
LR operator
^
(
L, R
)
|
||
|
LR operator
|
(
L, R
)
|
||
où
LR
est le résultat des
conversions arithmétiques usuelles
appliquées à
L
et
R
.
#include <bitset> #include <cstdint> #include <iomanip> #include <iostream> int main() { std::uint16_t mask = 0x00f0; std::uint32_t x0 = 0x12345678; std::uint32_t x1 = x0 | mask; std::uint32_t x2 = x0 & ~mask; std::uint32_t x3 = x0 & mask; std::uint32_t x4 = x0 ^ mask; std::uint32_t x5 = ~x0; using bin16 = std::bitset<16>; using bin32 = std::bitset<32>; std::cout << std::hex << std::showbase << "Masque : " << mask << std::setw(49) << bin16(mask) << "\n" "Valeur : " << x0 << std::setw(42) << bin32(x0) << "\n" "Définition des bits : " << x1 << std::setw(35) << bin32(x1) << "\n" "Effacement des bits : " << x2 << std::setw(34) << bin32(x2) << "\n" "Sélection des bits : " << x3 << std::setw(39) << bin32(x3) << "\n" "Bits XOR : " << x4 << std::setw(35) << bin32(x4) << "\n" "Inversion des bits : " << x5 << std::setw(33) << bin32(x5) << '\n'; }
Sortie :
Masque : 0xf0 0000000011110000 Valeur : 0x12345678 00010010001101000101011001111000 Définition des bits : 0x123456f8 00010010001101000101011011111000 Effacement des bits : 0x12345608 00010010001101000101011000001000 Sélection des bits : 0x70 00000000000000000000000001110000 Bits XOR : 0x12345688 00010010001101000101011010001000 Inversion des bits : 0xedcba987 11101101110010111010100110000111
Opérateurs de décalage binaire
Les expressions d'opérateur de décalage bit à bit ont la forme
lhs
<<
rhs
|
(1) | ||||||||
lhs
>>
rhs
|
(2) | ||||||||
Les opérateurs de décalage bit à bit ont une précédence plus élevée que les opérateurs logiques bit à bit, mais une précédence inférieure à celle des opérateurs additifs et multiplicatifs. Ces opérateurs s'associent de gauche à droite :
a >> b * c; // équivalent à a >> (b * c), PAS (a >> b) * c d << e & f; // équivalent à (d << e) & f, PAS d << (e & f) g << h >> i; // équivalent à (g << h) >> i, PAS g << (h >> i)
Opérateurs de décalage binaire intégrés
Pour les opérateurs de décalage binaire intégrés, les deux opérandes doivent être des prvalues de type entier ou d'énumération non délimitée. Des promotions entières sont effectuées sur les deux opérandes.
Dans la description restante de cette section, « opérande(s) », a , b , lhs et rhs font référence aux opérande(s) converti(s) ou promu(s).
Si la valeur de rhs est négative ou n'est pas inférieure au nombre de bits dans lhs , le comportement est indéfini.
|
Pour un type non signé
a
, la valeur de
a
<<
b
est la valeur de
a * 2
b
Pour un type signé et non négatif
a
, si
a * 2
b
Pour un a négatif, le comportement de a << b est indéfini.
Pour un type non signé
a
et pour un type signé et non négatif
a
, la valeur de
a
>>
b
est la partie entière de
a/2
b
Pour un a négatif, la valeur de a >> b est définie par l'implémentation (dans la plupart des implémentations, cela effectue un décalage arithmétique vers la droite, de sorte que le résultat reste négatif). |
(jusqu'à C++20) |
|
La valeur de
a
<<
b
est la valeur unique congrue à
a * 2
b
La valeur de
a
>>
b
est
a/2
b
|
(depuis C++20) |
Le type du résultat est celui de lhs .
Surcharges
Dans
la résolution de surcharge pour les opérateurs définis par l'utilisateur
, pour chaque paire de types entiers promus
L
et
R
, les signatures de fonctions suivantes participent à la résolution de surcharge :
|
L operator
<<
(
L, R
)
|
||
|
L operator
>>
(
L, R
)
|
||
#include <iostream> enum { ONE = 1, TWO = 2 }; int main() { std::cout << std::hex << std::showbase; char c = 0x10; unsigned long long ull = 0x123; std::cout << "0x123 << 1 = " << (ull << 1) << "\n" "0x123 << 63 = " << (ull << 63) << "\n" // dépassement en non signé "0x10 << 10 = " << (c << 10) << '\n'; // char est promu en int long long ll = -1000; std::cout << std::dec << "-1000 >> 1 = " << (ll >> ONE) << '\n'; }
Sortie :
0x123 << 1 = 0x246 0x123 << 63 = 0x8000000000000000 0x10 << 10 = 0x4000 -1000 >> 1 = -500
Bibliothèque standard
Les opérateurs arithmétiques sont surchargés pour de nombreux types de la bibliothèque standard.
Opérateurs arithmétiques unaires
|
implémente les opérateurs unaires + et -
(fonction membre publique de
std::chrono::duration<Rep,Period>
)
|
|
|
applique les opérateurs unaires aux nombres complexes
(fonction template) |
|
|
applique un opérateur arithmétique unaire à chaque élément du valarray
(fonction membre publique de
std::valarray<T>
)
|
Opérateurs additifs
|
(C++11)
|
effectue des opérations d'addition et de soustraction impliquant un point temporel
(modèle de fonction) |
|
implémente des opérations arithmétiques avec des durées comme arguments
(modèle de fonction) |
|
|
(C++20)
|
ajoute ou soustrait un
year_month_day
et un certain nombre d'années ou de mois
(fonction) |
|
concatène deux chaînes, une chaîne et un
char
, ou une chaîne et une
string_view
(modèle de fonction) |
|
|
avance ou décrémente l'itérateur
(fonction membre publique de
std::reverse_iterator<Iter>
)
|
|
|
avance ou décrémente l'itérateur
(fonction membre publique de
std::move_iterator<Iter>
)
|
|
|
effectue des opérations arithmétiques sur deux nombres complexes ou un complexe et un scalaire
(modèle de fonction) |
|
|
applique des opérateurs binaires à chaque élément de deux valarrays, ou un valarray et une valeur
(modèle de fonction) |
Opérateurs multiplicatifs
|
implémente les opérations arithmétiques avec des durées comme arguments
(modèle de fonction) |
|
|
effectue des opérations arithmétiques sur des nombres complexes entre deux valeurs complexes ou entre un complexe et un scalaire
(modèle de fonction) |
|
|
applique des opérateurs binaires à chaque élément de deux valarrays, ou d'un valarray et d'une valeur
(modèle de fonction) |
Opérateurs logiques bit à bit
|
effectue les opérations binaires ET, OU, XOR et NON
(fonction membre publique de
std::bitset<N>
)
|
|
|
effectue des opérations logiques binaires sur les bitsets
(fonction template) |
|
|
applique un opérateur arithmétique unaire à chaque élément du valarray
(fonction membre publique de
std::valarray<T>
)
|
|
|
applique des opérateurs binaires à chaque élément de deux valarrays, ou d'un valarray et d'une valeur
(fonction template) |
Opérateurs de décalage binaire
|
applique des opérateurs binaires à chaque élément de deux valarrays, ou d'un valarray et d'une valeur
(modèle de fonction) |
|
|
effectue un décalage binaire vers la gauche et vers la droite
(fonction membre publique de
std::bitset<N>
)
|
Opérateurs d'insertion/extraction de flux
Dans la bibliothèque standard, les opérateurs de décalage bit à bit sont couramment surchargés avec les flux d'E/S ( std:: ios_base & ou l'une des classes qui en dérivent) comme opérande gauche et type de retour. Ces opérateurs sont connus sous le nom d' opérateurs d'insertion de flux et d' opérateurs d'extraction de flux :
|
extrait des données formatées
(fonction membre publique de
std::basic_istream<CharT,Traits>
)
|
|
|
extrait des caractères et tableaux de caractères
(modèle de fonction) |
|
|
insère des données formatées
(fonction membre publique de
std::basic_ostream<CharT,Traits>
)
|
|
|
insère des données caractère ou insertion dans un flux rvalue
(modèle de fonction) |
|
|
sérialise et désérialise un nombre complexe
(modèle de fonction) |
|
|
effectue l'entrée/sortie de flux sur les bitsets
(modèle de fonction) |
|
|
effectue l'entrée/sortie de flux sur les chaînes
(modèle de fonction) |
|
|
(C++11)
|
effectue l'entrée/sortie de flux sur un moteur de nombres pseudo-aléatoires
(modèle de fonction) |
|
(C++11)
|
effectue l'entrée/sortie de flux sur une distribution de nombres pseudo-aléatoires
(modèle de fonction) |
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement tel que publié | Comportement correct |
|---|---|---|---|
| CWG 614 | C++98 |
le quotient algébrique de la division entière était
arrondi dans une direction définie par l'implémentation |
le quotient algébrique de la division
entière est tronqué vers zéro (la partie fractionnaire est ignorée) |
| CWG 1450 | C++98 |
le résultat de
a
/
b
était non spécifié si
il n'est pas représentable dans le type de résultat |
le comportement de
a
/
b
et
a % b est indéfini dans ce cas |
| CWG 1457 | C++98 |
le comportement du décalage du bit
1
le plus à gauche d'une
valeur signée positive dans le bit de signe était indéfini |
rendu bien défini |
| CWG 1504 | C++98 |
un pointeur vers un sous-objet de classe de base d'un élément
de tableau pouvait être utilisé dans l'arithmétique des pointeurs |
le comportement est
indéfini dans ce cas |
| CWG 1515 | C++98 |
seuls les entiers non signés déclarés
unsigned
devaient obéir aux lois de l'arithmétique modulo 2 n |
s'applique à tous les entiers non signés |
| CWG 1642 | C++98 | les opérateurs arithmétiques autorisaient leurs opérandes à être des lvalues | certains opérandes doivent être des rvalues |
| CWG 1865 | C++98 |
la résolution de
CWG issue 1504
rendait les comportements
de l'arithmétique des pointeurs impliquant des pointeurs vers des éléments de tableau indéfinis si le type pointé et le type de l'élément du tableau ont des qualifications cv différentes dans les niveaux non supérieurs |
rendu bien défini |
| CWG 1971 | C++98 |
il n'était pas clair si la règle résolvant l'
ambiguïté de ~ s'appliquait à des cas tels que ~X ( 0 ) |
la règle s'applique à de tels cas |
| CWG 2419 | C++98 |
un pointeur vers un objet non-tableau n'était traité comme un
pointeur vers le premier élément d'un tableau de taille 1 dans l'arithmétique des pointeurs que si le pointeur est obtenu par & |
s'applique à tous les pointeurs
vers des objets non-tableau |
| CWG 2626 | C++98 |
le résultat de l'opérateur intégré
operator~
était simplement
'complément à un' sans définition appropriée |
le résultat est formulé en termes
de représentation en base 2 |
| CWG 2724 | C++20 | la direction d'arrondi du décalage arithmétique à droite n'était pas claire | clarifiée |
| CWG 2853 | C++98 |
un pointeur au-delà de la fin d'un objet ne pouvait
pas être ajouté ou soustrait avec un entier |
il peut l'être |
Voir aussi
| Opérateurs courants | ||||||
|---|---|---|---|---|---|---|
| affectation |
incrémentation
décrémentation |
arithmétique | logique | comparaison |
accès
membre |
autre |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
...
]
|
appel de fonction
a ( ... ) |
|
virgule
a, b |
||||||
|
conditionnel
a ? b : c |
||||||
| Opérateurs spéciaux | ||||||
|
static_cast
convertit un type en un autre type apparenté
|
||||||
|
Documentation C
pour
Opérateurs arithmétiques
|