Namespaces
Variants

Increment/decrement operators

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Les opérateurs d'incrémentation/décrémentation incrémentent ou décrémentent la valeur de l'objet.

Nom de l'opérateur Syntaxe Surchargeable Exemples de prototypes (pour class T )
Définition interne à la classe Définition externe à la classe
Pré-incrémentation ++a Oui T & T :: operator ++ ( ) ; T & operator ++ ( T & a ) ;
Pré-décrémentation --a Oui T & T :: operator -- ( ) ; T & operator -- ( T & a ) ;
Post-incrémentation a++ Oui T T :: operator ++ ( int ) ; T operator ++ ( T & a, int ) ;
Post-décrémentation a-- Oui T T :: operator -- ( int ) ; T operator -- ( T & a, int ) ;
Notes
  • Les versions préfixes des opérateurs intégrés retournent des références et les versions postfixes retournent des valeurs , et les surcharges définies par l'utilisateur typiques suivent ce modèle afin que les opérateurs définis par l'utilisateur puissent être utilisés de la même manière que les opérateurs intégrés. Cependant, dans une surcharge d'opérateur définie par l'utilisateur, n'importe quel type peut être utilisé comme type de retour (y compris void ).
  • Le paramètre int est un paramètre factice utilisé pour différencier les versions préfixes et postfixes des opérateurs. Lorsque l'opérateur postfixe défini par l'utilisateur est appelé, la valeur passée dans ce paramètre est toujours zéro, bien qu'elle puisse être modifiée en appelant l'opérateur en utilisant la notation d'appel de fonction (par exemple, a. operator ++ ( 2 ) ou operator ++ ( a, 2 ) ).

Table des matières

Opérateurs préfixes

Les expressions de pré-incrémentation et pré-décrémentation ont la forme

++ expression
-- expression
1) incrémentation de préfixe (pré-incrémentation)
2) décrémentation de préfixe (pré-décrémentation)

Opérateurs préfixes intégrés

1) L'expression ++ x est équivalente à x + = 1 , avec les exceptions suivantes :
  • Si le type de l'expression est (éventuellement qualifié volatile) bool , l'expression est définie à true . Un tel incrément est déprécié.
(jusqu'en C++17)
  • Si le type de l'expression est (éventuellement qualifié cv) bool , le programme est mal formé.
(depuis C++17)
  • Si le type de l'expression est qualifié volatile, l'incrément est déprécié.
(depuis C++20)
2) L'expression -- x est équivalente à x - = 1 , avec les exceptions suivantes :
  • Si le type de expression est (éventuellement qualifié cv) bool , le programme est mal formé.
  • Si le type de expression est qualifié volatile, le décrément est déprécié.
(depuis C++20)

Surcharges

Dans la résolution de surcharge pour les opérateurs définis par l'utilisateur , pour chaque type arithmétique A éventuellement qualifié volatile autre que bool , et pour chaque pointeur P éventuellement qualifié volatile vers un type objet éventuellement qualifié cv, les signatures de fonction suivantes participent à la résolution de surcharge :

A & operator ++ ( A & )
bool & operator ++ ( bool & )
(obsolète) (jusqu'à C++17)
P & operator ++ ( P & )
A & operator -- ( A & )
P & operator -- ( P & )

Opérateurs postfixés

Les expressions d'incrémentation et de décrémentation postfixées ont la forme

expression ++
expression --
1) incrémentation postfixée (post-incrémentation)
2) décrémentation postfixée (post-décrémentation)

Opérateurs postfixés intégrés

Le résultat de l'incrémentation ou de la décrémentation postfixe est la valeur obtenue en appliquant la conversion lvalue-vers-rvalue à expression (avant modification). Le type du résultat est la version non qualifiée cv du type de expression .

Si expression n'est pas une lvalue modifiable d'un type arithmétique autre que (éventuellement qualifié cv) bool (depuis C++17) , ou un pointeur vers un type objet complet, le programme est mal formé.

Si le type de expression est qualifié volatile, l'incrément ou le décrément est déprécié.

(since C++20)
1) La valeur de l' expression est modifiée comme s'il s'agissait de l'opérande de l'opérateur préfixe ++ .
2) La valeur de l' expression est modifiée comme si elle était l'opérande de l'opérateur préfixe -- .

Le calcul de la valeur d'un incrément ou décrément postfixé est séquencé avant la modification de l'expression . Par rapport à un appel de fonction indéterminément séquencé, l'opération d'un incrément ou décrément postfixé est une évaluation unique.

Surcharges

Dans la résolution de surcharge pour les opérateurs définis par l'utilisateur , pour chaque type arithmétique A éventuellement qualifié volatile autre que bool , et pour chaque pointeur P éventuellement qualifié volatile vers un type objet éventuellement qualifié cv, les signatures de fonction suivantes participent à la résolution de surcharge :

A operator ++ ( A & , int )
bool operator ++ ( bool & , int )
(obsolète) (jusqu'à C++17)
P operator ++ ( P & , int )
A operator -- ( A & , int )
P operator -- ( P & , int )

Exemple

#include <iostream>
int main()
{
    int n1 = 1;
    int n2 = ++n1;
    int n3 = ++ ++n1;
    int n4 = n1++;
//  int n5 = n1++ ++;   // error
//  int n6 = n1 + ++n1; // undefined behavior
    std::cout << "n1 = " << n1 << '\n'
              << "n2 = " << n2 << '\n'
              << "n3 = " << n3 << '\n'
              << "n4 = " << n4 << '\n';
}

Sortie :

n1 = 5
n2 = 2
n3 = 4
n4 = 4

Notes

En raison des effets secondaires impliqués, les opérateurs intégrés d'incrémentation et de décrémentation doivent être utilisés avec précaution pour éviter un comportement indéfini dû à des violations des règles de séquencement .

Parce qu'une copie temporaire de l'objet est construite lors de la post-incrémentation et de la post-décrémentation, les opérateurs de pré-incrémentation ou de pré-décrémentation sont généralement plus efficaces dans les contextes où la valeur retournée n'est pas utilisée.

Bibliothèque standard

Les opérateurs d'incrémentation et de décrémentation sont surchargés pour de nombreux types de la bibliothèque standard. En particulier, chaque LegacyIterator surcharge operator ++ et chaque LegacyBidirectionalIterator surcharge operator -- , même si ces opérateurs sont des no-ops pour l'itérateur particulier.

surcharges pour les types arithmétiques
incrémente ou décrémente la valeur atomique de un
(fonction membre publique de std::atomic<T> )
incrémente ou décrémente le compteur de ticks
(fonction membre publique de std::chrono::duration<Rep,Period> )
surcharges pour les types itérateurs
avance l'itérateur
(fonction membre publique de std::raw_storage_iterator<OutputIt,T> )
avance ou décrémente le reverse_iterator
(fonction membre publique de std::reverse_iterator<Iter> )
avance ou décrémente le move_iterator
(fonction membre publique de std::move_iterator<Iter> )
opération nulle
(fonction membre publique de std::front_insert_iterator<Container> )
opération nulle
(fonction membre publique de std::back_insert_iterator<Container> )
opération nulle
(fonction membre publique de std::insert_iterator<Container> )
avance l'itérateur
(fonction membre publique de std::istream_iterator<T,CharT,Traits,Distance> )
opération nulle
(fonction membre publique de std::ostream_iterator<T,CharT,Traits> )
avance l'itérateur
(fonction membre publique de std::istreambuf_iterator<CharT,Traits> )
opération nulle
(fonction membre publique de std::ostreambuf_iterator<CharT,Traits> )
avance l'itérateur vers la correspondance suivante
(fonction membre publique de std::regex_iterator<BidirIt,CharT,Traits> )
avance l'itérateur vers la sous-correspondance suivante
(fonction membre publique de std::regex_token_iterator<BidirIt,CharT,Traits> )

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 publié Comportement corrigé
CWG 2855 C++98 les conversions arithmétiques usuelles étaient appliquées pour les opérateurs de pré-incrément et
pré-décrément intégrés, mais pas pour leurs équivalents postfixés [1]
également appliquées
CWG 2901 C++98 les conversions lvalue-vers-rvalue n'étaient pas appliquées
pour les opérateurs de post-incrément et post-décrément intégrés
appliquées
  1. Le préfixe ++ x est équivalent à x + = 1 , et ce dernier est soumis aux conversions arithmétiques usuelles (c'est-à-dire produit un type commun entre decltype ( x ) et int ). Cependant, l'effet du postfixe x ++ est simplement « ajouter un à x », il n'y a pas d'opérateur binaire présent, donc aucune conversion arithmétique usuelle n'aura lieu.

Voir aussi

Priorité des opérateurs

Surcharge d'opérateur

Opérateurs courants
affectation incrémentation
décrémentation
arithmétique logique comparaison accès
membre
autre

a = b
a + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b
a <=> b

a [ ... ]
* a
& a
a - > b
a. b
a - > * b
a. * b

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é
dynamic_cast convertit au sein des hiérarchies d'héritage
const_cast ajoute ou supprime les qualificateurs cv
reinterpret_cast convertit un type en un type non apparenté
C-style cast convertit un type en un autre par un mélange de static_cast , const_cast , et reinterpret_cast
new crée des objets avec une durée de stockage dynamique
delete détruit les objets précédemment créés par l'expression new et libère la zone mémoire obtenue
sizeof interroge la taille d'un type
sizeof... interroge la taille d'un pack (depuis C++11)
typeid interroge les informations de type d'un type
noexcept vérifie si une expression peut lever une exception (depuis C++11)
alignof interroge les exigences d'alignement d'un type (depuis C++11)

Documentation C pour Opérateurs d'incrémentation/décrémentation