Namespaces
Variants

Other 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
Opérateur
nom
Syntaxe Surchargeable Exemples de prototypes (pour class T )
Définition interne à la classe Définition externe à la classe
appel de fonction a(a1, a2) Oui R T :: operator ( ) ( Arg1 & a1, Arg2 & a2, ... ) ; N/A
virgule a, b Oui T2 & T :: operator , ( T2 & b ) ; T2 & operator, ( const T & a, T2 & b ) ;
opérateur conditionnel a ? b : c Non N/A N/A

L'opérateur d' appel de fonction fournit une sémantique de fonction pour tout objet.

L' opérateur conditionnel (communément appelé ternaire conditionnel ) vérifie la valeur booléenne de la première expression et, selon la valeur résultante, évalue et retourne soit la deuxième, soit la troisième expression.

Table des matières

Opérateur d'appel de fonction intégré

Les expressions d'appel de fonction ont la forme suivante :

fonction  ( arg1 , arg2 , arg3 , ... )
function - un type de fonction d'expression ou un type de pointeur de fonction
arg1 , arg2 , arg3 , ... - une liste éventuellement vide d'expressions arbitraires ou de listes d'initialisation entre accolades (depuis C++11) , sauf que l'opérateur virgule n'est pas autorisé au niveau supérieur pour éviter toute ambiguïté

Pour un appel à une fonction non-membre ou à une fonction membre statique , function peut être une lvalue qui réfère à une fonction (auquel cas la conversion fonction-vers-pointeur est supprimée), ou une prvalue de type pointeur de fonction.

Le nom de fonction (ou de membre) spécifié par function peut être surchargé, les règles de résolution de surcharge sont utilisées pour déterminer quelle surcharge doit être appelée.

Si function spécifie une fonction membre, elle peut être virtuelle, auquel cas le remplacement final de cette fonction sera appelé, en utilisant la dispatch dynamique à l'exécution.

Chaque paramètre de fonction est initialisé avec son argument correspondant après conversion implicite si nécessaire.

  • S'il n'y a pas d'argument correspondant, l' argument par défaut correspondant est utilisé, et s'il n'y en a pas, le programme est mal formé.
  • Si l'appel est fait à une fonction membre, alors le pointeur this vers l'objet courant est converti comme par un cast explicite vers le pointeur this attendu par la fonction.
  • L'initialisation et la destruction de chaque paramètre se produisent dans le contexte de l' expression complète où l'appel de fonction apparaît, ce qui signifie, par exemple, que si un constructeur ou un destructeur d'un paramètre lève une exception, les blocs try de fonction de la fonction appelée ne sont pas pris en compte.

Si la fonction est une fonction variadique, les promotions d'arguments par défaut sont appliquées à tous les arguments correspondant au paramètre ellipsis.

Il est défini par l'implémentation si un paramètre est détruit lorsque la fonction dans laquelle il est défini se termine ou à la fin de l'expression complète englobante. Les paramètres sont toujours détruits dans l'ordre inverse de leur construction.

Le type de retour d'une expression d'appel de fonction est le type de retour de la fonction choisie, déterminé en utilisant la liaison statique (en ignorant le mot-clé virtual ), même si la fonction de redéfinition effectivement appelée retourne un type différent. Cela permet aux fonctions de redéfinition de retourner des pointeurs ou des références vers des classes dérivées du type de retour de la fonction de base, c'est-à-dire que C++ prend en charge les types de retour covariants . Si la fonction spécifie un destructeur, le type de retour est void .

Lorsqu'un objet de type classe X est passé à ou retourné par une fonction, si chaque constructeur de copie, constructeur de déplacement et destructeur de X est soit trivial soit supprimé, et que X a au moins un constructeur de copie ou de déplacement non supprimé, les implémentations sont autorisées à créer un objet temporaire pour contenir le paramètre de fonction ou l'objet résultat.

L'objet temporaire est construit à partir de l'argument de fonction ou de la valeur de retour, respectivement, et le paramètre de fonction ou l'objet de retour est initialisé comme si on utilisait le constructeur trivial non supprimé pour copier le temporaire (même si ce constructeur est inaccessible ou ne serait pas sélectionné par la résolution de surcharge pour effectuer une copie ou un déplacement de l'objet).

Cela permet à des objets de petits types de classe, tels que std::complex ou std::span , d'être passés à ou retournés par des fonctions dans des registres.

(depuis C++17)

La catégorie de valeur d'une expression d'appel de fonction est lvalue si la fonction retourne une référence lvalue ou une référence rvalue vers fonction, est une xvalue si la fonction retourne une référence rvalue vers objet, et est une prvalue sinon. Si l'expression d'appel de fonction est une prvalue de type objet, elle doit avoir un type complet sauf lorsqu'elle est utilisée comme opérande de decltype (ou comme opérande droit d'un opérateur virgule intégré qui est l'opérande de decltype ) (depuis C++11) .

Lorsque la fonction appelée se termine normalement, toutes les assertions de postcondition de la fonction sont évaluées en séquence . Si l'implémentation introduit des objets temporaires pour contenir la valeur de résultat, pour l'évaluation E de chaque assertion de postcondition :

(depuis C++26)

L'expression d'appel de fonction est similaire en syntaxe à l'initialisation de valeur T ( ) , à l'expression de cast de style fonction T ( A1 ) , et à l'initialisation directe d'un temporaire T ( A1, A2, A3, ... ) , où T est le nom d'un type.

#include <cstdio>
struct S
{
    int f1(double d)
    {
        return printf("%f \n", d); // appel de fonction à nombre variable d'arguments
    }
    int f2()
    {
        return f1(7); // appel de fonction membre, identique à this->f1()
                      // argument entier converti en double
    }
};
void f()
{
    puts("function called"); // appel de fonction
}
int main()
{
    f();    // appel de fonction
    S s;
    s.f2(); // appel de fonction membre
}

Sortie :

function called
7.000000

Opérateur virgule intégré

Les expressions virgule ont la forme suivante :

E1 , E2

Dans une expression virgule E1, E2 , l'expression E1 est évaluée, son résultat est rejeté (bien que si elle a un type classe, elle ne sera pas détruite avant la fin de l'expression complète contenante ), et ses effets secondaires sont complétés avant que l'évaluation de l'expression E2 ne commence (notez qu'un operator, défini par l'utilisateur ne peut garantir le séquencement) (jusqu'à C++17) .

Le type, la valeur et la catégorie de valeur du résultat de l'expression virgule sont exactement le type, la valeur et la catégorie de valeur du second opérande, E2 . Si E2 est une expression temporaire expression (since C++17) , le résultat de l'expression est cette expression temporaire expression (since C++17) . Si E2 est un champ de bits, le résultat est un champ de bits.

La virgule dans diverses listes séparées par des virgules, telles que les listes d'arguments de fonction ( f ( a, b, c ) ) et les listes d'initialisation int a [ ] = { 1 , 2 , 3 } , n'est pas l'opérateur virgule. Si l'opérateur virgule doit être utilisé dans de tels contextes, il doit être mis entre parenthèses : f ( a, ( n ++ , n + b ) , c ) .

L'utilisation d'une expression virgule non parenthésée comme second argument (droit) d'un opérateur d'indice est dépréciée.

Par exemple, a [ b, c ] est déprécié alors que a [ ( b, c ) ] ne l'est pas.

(depuis C++20)
(jusqu'à C++23)

Une expression virgule non parenthésée ne peut pas être le second argument (droit) d'un opérateur d'indice . Par exemple, a [ b, c ] est soit mal formé soit équivalent à a. operator [ ] ( b, c ) .

Des parenthèses sont nécessaires lors de l'utilisation d'une expression virgule comme indice, par exemple, a [ ( b, c ) ] .

(depuis C++23)
#include <iostream>
int main()
{
    // la virgule est souvent utilisée pour exécuter plus d'une expression
    // là où la grammaire du langage n'autorise qu'une seule expression :
    // * dans la troisième composante de la boucle for
    for (int i = 0, j = 10; i <= j; ++i, --j)
    //            ^séparateur de liste      ^opérateur virgule
        std::cout << "i = " << i << " j = " << j << '\n';
    // * dans une instruction return
    // return log("an error!"), -1;
    // * dans une expression d'initialisation
    // MyClass(const Arg& arg)
    // : member{ throws_if_bad(arg), arg }
    // etc.
    // les opérateurs virgule peuvent être chaînés ; le résultat de la dernière
    // (la plus à droite) expression est le résultat de toute la chaîne :
    int n = 1;
    int m = (++n, std::cout << "n = " << n << '\n', ++n, 2 * n);
    // m vaut maintenant 6
    std::cout << "m = " << (++m, m) << '\n';
}

Sortie :

i = 0 j = 10
i = 1 j = 9
i = 2 j = 8
i = 3 j = 7
i = 4 j = 6
i = 5 j = 5
n = 2
m = 7

Opérateur conditionnel

Les expressions de l'opérateur conditionnel ont la forme

E1 ? E2 : E3

E1 est évalué et contextuellement converti en bool , si le résultat est true , le résultat de l'expression conditionnelle est la valeur de E2 ; sinon le résultat de l'expression conditionnelle est la valeur de E3 .

Le type et la catégorie de valeur de l'expression conditionnelle E1 ? E2 : E3 sont déterminés comme suit :

Étape 1

Si à la fois E2 et E3 sont de type void , le résultat est une rvalue (jusqu'en C++11) une prvalue (depuis C++11) de type void .

Si exactement l'un des E2 et E3 est de type void :

Si ni E2 ni E3 n'est de type void , passez à l'étape suivante.

2 + 2 == 4 ? throw 123 : throw 456; // le résultat est de type « void »
2 + 2 != 4 ? "OK" : throw "error";  // le résultat est de type « const char[3] »
                                    // même si une exception est toujours levée

Étape 2

Si E2 ou E3 sont des champs de bits lvalue (jusqu'en C++11) champs de bits glvalue de même catégorie de valeur (depuis C++11) et de types cv1 T et cv2 T , respectivement, les opérandes sont considérés comme étant de type cv T pour le reste du processus, où cv est l'union de cv1 et cv2 .

Si E2 et E3 ont des types différents, et qu'une des conditions suivantes est satisfaite, passez à l'étape 3 :

  • Au moins l'un des E2 et E3 est un type classe (éventuellement qualifié cv).
  • Les deux E2 et E3 sont des lvalues du même type (jusqu'en C++11) des glvalues de la même catégorie de valeur et du même type (depuis C++11) à l'exception de la qualification cv.

Sinon, passez à l'étape 4.

Étape 3

Des tentatives sont faites pour former une séquence de conversion implicite [2] à partir d'une expression opérande X de type TX vers un type cible lié au type TY de l'expression opérande Y comme suit :

  • Si Y est une lvalue, le type cible est TY& , mais une séquence de conversion implicite ne peut être formée que si la référence se lie directement à une lvalue (jusqu'à C++11) une glvalue (depuis C++11) .
  • Si Y est une xvalue, le type cible est TY&& , mais une séquence de conversion implicite ne peut être formée que si la référence se lierait directement.
(depuis C++11)
  • Si Y est une rvalue (jusqu'en C++11) une prvalue (depuis C++11) ou si aucune des séquences de conversion ci-dessus ne peut être formée, et qu'au moins l'un des types TX et TY est un type classe (éventuellement qualifié cv) :
    • Si TX et TY sont le même type de classe (en ignorant la qualification cv) :
      • Si TY est au moins aussi qualifié cv que TX , le type cible est TY .
      • Sinon, aucune séquence de conversion n'est formée.
    • Sinon, si TY est une classe de base de TX , le type cible est TY avec les qualifications cv de TX .
    • Sinon, le type cible est le type de Z , où Z est la valeur de Y après application des conversions standard lvalue-vers-rvalue, tableau-vers-pointeur et fonction-vers-pointeur.
  • Sinon, aucune séquence de conversion n'est formée.

En utilisant ce processus, il est déterminé si une séquence de conversion implicite peut être formée de E2 vers le type cible déterminé pour E3 , et vice versa.

  • Si aucune séquence de conversion ne peut être formée, passez à l'étape suivante.
  • Si exactement une séquence de conversion peut être formée :
    • Si la séquence de conversion est ambiguë, le programme est mal formé.
    • Sinon, cette conversion est appliquée à l'opérande choisi et l'opérande converti est utilisé à la place de l'opérande original pour le processus restant, et passez à l'étape suivante.
  • Si les deux séquences peuvent être formées, le programme est mal formé.
struct A {};
struct B : A {};
using T = const B;
A a = true ? A() : T(); // Y = A(), TY = A, X = T(), TX = const B, Cible = const A

Étape 4

Si E2 et E3 sont des lvalues du même type, alors le résultat est une lvalue de ce type, et est un champ de bits si au moins l'un des E2 et E3 est un champ de bits.

(jusqu'à C++11)

Si E2 et E3 sont des glvalues du même type et de la même catégorie de valeur, alors le résultat a le même type et la même catégorie de valeur, et est un champ de bits si au moins l'un des E2 et E3 est un champ de bits.

(depuis C++11)

Sinon, le résultat est un rvalue (jusqu'à C++11) un prvalue (depuis C++11) .

  • Si E2 et E3 n'ont pas le même type, et que l'un ou l'autre a un type de classe (éventuellement qualifié cv), passez à l'étape 5.
  • Sinon, passez à l'étape 6.

Étape 5

Résolution de surcharge est effectuée en utilisant les candidats intégrés pour tenter de convertir les opérandes en types intégrés :

  • Si la résolution de surcharge échoue, le programme est mal formé.
  • Sinon, les conversions sélectionnées sont appliquées et les opérandes converties sont utilisées à la place des opérandes originales pour le processus restant. Passez à l'étape suivante.

Étape 6

Les conversions tableau-vers-pointeur et fonction-vers-pointeur sont appliquées à (éventuellement converties) E2 et E3 . Après ces conversions, au moins l'une des conditions suivantes doit être satisfaite, sinon le programme est mal formé :

  • E2 et E3 ont le même type. Dans ce cas, le résultat est de ce type et est initialisé par copie en utilisant l'opérande sélectionné.
  • Les deux E2 et E3 ont un type arithmétique ou énumération. Dans ce cas, les conversions arithmétiques usuelles sont appliquées pour les amener à leur type commun, et le résultat est de ce type.
  • Au moins l'un des E2 et E3 est un pointeur. Dans ce cas, les conversions lvalue-vers-rvalue, pointeur , pointeur de fonction (depuis C++17) et de qualification sont appliquées pour les amener à leur type de pointeur composite , et le résultat est de ce type.
  • Au moins l'un des E2 et E3 est un pointeur vers membre. Dans ce cas, les conversions lvalue-vers-rvalue, pointeur-vers-membre , pointeur de fonction (depuis C++17) et de qualification sont appliquées pour les amener à leur type de pointeur composite , et le résultat est de ce type.
  • Les deux E2 et E3 sont des constantes de pointeur nul, et au moins l'un d'entre eux est de type std::nullptr_t . Dans ce cas, le résultat est de type std::nullptr_t .
(depuis C++11)
int* intPtr;
using Mixed = decltype(true ? nullptr : intPtr);
static_assert(std::is_same_v<Mixed, int*>); // nullptr devenant int*
struct A
{
    int* m_ptr;
} a;
int* A::* memPtr = &A::m_ptr; // memPtr est un pointeur vers le membre m_ptr de A
// memPtr fait de nullptr un type de pointeur vers le membre m_ptr de A
static_assert(std::is_same_v<decltype(false ? memPtr : nullptr), int*A::*>);
// a.*memPtr est maintenant juste un pointeur vers int et nullptr devient également pointeur vers int
static_assert(std::is_same_v<decltype(false ? a.*memPtr : nullptr), int*>);
  1. Un tel opérateur conditionnel était couramment utilisé dans la programmation constexpr de C++11 avant C++14.
  2. L'accès aux membres , si une fonction de conversion est supprimée (depuis C++11) et si un opérande est un champ de bits sont ignorés.

Le type résultant d'un opérateur conditionnel est également accessible en tant que trait de type binaire std::common_type .

(depuis C++11)

Surcharges

Pour chaque paire de types arithmétiques promus L et R et pour chaque type P , où P est un type pointeur, pointeur-sur-membre ou énumération scopée, les signatures de fonction suivantes participent à la résolution de surcharge :

LR opérateur ?: ( bool , L, R ) ;
P opérateur ?: ( bool , P, P ) ;

où LR est le résultat des conversions arithmétiques habituelles appliquées à L et R .

L'opérateur « ?: » ne peut pas être surchargé, ces signatures de fonction existent uniquement à des fins de résolution de surcharge.

#include <iostream>
#include <string>
struct Node
{
    Node* next;
    int data;
    // deep-copying copy constructor
    Node(const Node& other)
        : next(other.next ? new Node(*other.next) : NULL)
        , data(other.data)
    {}
    Node(int d) : next(NULL), data(d) {}
    ~Node() { delete next; }
};
int main()
{   
    // simple rvalue example
    int n = 1 > 2 ? 10 : 11;  // 1 > 2 is false, so n = 11
    // simple lvalue example
    int m = 10; 
    (n == m ? n : m) = 7; // n == m is false, so m = 7
    //output the result
    std::cout << "n = " << n << "\nm = " << m;
}

Sortie :

n = 11
m = 7

Bibliothèque standard

De nombreuses classes de la bibliothèque standard surchargent operator() pour être utilisées comme objets fonction.

supprime l'objet ou le tableau
(fonction membre publique de std::default_delete<T> )
retourne la somme de deux arguments
(fonction membre publique de std::plus<T> )
retourne la différence entre deux arguments
(fonction membre publique de std::minus<T> )
renvoie le produit de deux arguments
(fonction membre publique de std::multiplies<T> )
renvoie le résultat de la division du premier argument par le deuxième argument
(fonction membre publique de std::divides<T> )
renvoie le reste de la division du premier argument par le deuxième argument
(fonction membre publique de std::modulus<T> )
retourne la négation de l'argument
(fonction membre publique de std::negate<T> )
vérifie si les arguments sont égaux
(fonction membre publique de std::equal_to<T> )
vérifie si les arguments ne sont pas égaux
(fonction membre publique de std::not_equal_to<T> )
vérifie si le premier argument est supérieur au second
(fonction membre publique de std::greater<T> )
vérifie si le premier argument est inférieur au second
(fonction membre publique de std::less<T> )
vérifie si le premier argument est supérieur ou égal au second
(fonction membre publique de std::greater_equal<T> )
vérifie si le premier argument est inférieur ou égal au second
(fonction membre publique de std::less_equal<T> )
renvoie le ET logique des deux arguments
(fonction membre publique de std::logical_and<T> )
retourne le OU logique des deux arguments
(fonction membre publique de std::logical_or<T> )
renvoie le NON logique de l'argument
(fonction membre publique de std::logical_not<T> )
renvoie le résultat de l'opération ET bit à bit de deux arguments
(fonction membre publique de std::bit_and<T> )
renvoie le résultat de l'opération OU binaire de deux arguments
(fonction membre publique de std::bit_or<T> )
renvoie le résultat du OU exclusif bit à bit de deux arguments
(fonction membre publique de std::bit_xor<T> )
renvoie le complément logique du résultat d'un appel au prédicat stocké
(fonction membre publique de std::unary_negate<Predicate> )
renvoie le complément logique du résultat de l'appel au prédicat stocké
(fonction membre publique de std::binary_negate<Predicate> )
appelle la fonction stockée
(fonction membre publique de std::reference_wrapper<T> )
invoque la cible
(fonction membre publique de std::function<R(Args...)> )
invoque la cible
(fonction membre publique de std::move_only_function )
invoque la cible
(fonction membre publique de std::copyable_function )
reprend l'exécution de la coroutine
(fonction membre publique de std::coroutine_handle<Promise> )
compare lexicographiquement deux chaînes en utilisant la facette de collation de cette locale
(fonction membre publique de std::locale )
compare deux valeurs de type value_type
(fonction membre publique de std::map<Key,T,Compare,Allocator>::value_compare )
compare deux valeurs de type value_type
(fonction membre publique de std::multimap<Key,T,Compare,Allocator>::value_compare )
exécute la fonction
(fonction membre publique de std::packaged_task<R(Args...)> )
avance l'état du moteur et retourne la valeur générée
(fonction membre publique de std::linear_congruential_engine<UIntType,a,c,m> )
(C++11)
génère le prochain nombre aléatoire dans la distribution
(fonction membre publique de std::uniform_int_distribution<IntType> )

L'opérateur virgule n'est surchargé par aucune classe de la bibliothèque standard. La bibliothèque Boost utilise operator, dans boost.assign , boost.spirit , et d'autres bibliothèques. La bibliothèque d'accès aux bases de données SOCI surcharge également operator, .

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 446 C++98 il n'était pas spécifié si un temporaire était créé pour une
conversion lvalue-vers-rvalue sur l'opérateur conditionnel
crée toujours un temporaire si
l'opérateur retourne une rvalue de classe
CWG 462 C++98 si le second opérande d'un opérateur virgule est un temporaire,
il n'était pas spécifié si sa durée de vie serait étendue lorsque
le résultat de l'expression virgule est lié à une référence
le résultat de l'expression virgule
est le temporaire dans ce cas
(donc sa durée de vie est étendue)
CWG 587 C++98 lorsque les deuxième et troisième opérandes d'un opérateur
conditionnel sont des lvalues du même type sauf pour
la qualification cv, le résultat était une lvalue si ces
opérandes avaient des types classe ou une rvalue sinon
le résultat est toujours
une lvalue dans ce cas
CWG 1029 C++98 le type d'un appel de destructeur n'était pas spécifié spécifié comme void
CWG 1550 C++98 les expressions throw parenthésées n'étaient pas autorisées dans
les expressions conditionnelles si l'autre opérande est non- void
accepté
CWG 1560 C++98 void comme opérande des opérateurs conditionnels provoquait
une conversion lvalue-vers-rvalue superflue sur l'
autre opérande, résultant toujours en une rvalue
une expression conditionnelle
avec un void peut être une lvalue
CWG 1642 C++98 l'expression fonction dans une expression d'appel de
fonction pouvait être une lvalue de pointeur de fonction
non autorisé
CWG 1805 C++98 lors de la détermination du type cible pour la séquence de
conversion implicite, la manière de convertir Y en Z n'était pas claire
clarifié
CWG 1895 C++98
C++11
pas clair si une fonction de conversion supprimée (C++11) ou
inaccessible (C++98) empêche la conversion dans les
expressions conditionnelles, et les conversions de prvalue
de classe de base vers classe dérivée n'étaient pas considérées
traité comme la
résolution de surcharge
CWG 1932 C++98 les champs de bits de même type manquaient dans les expressions conditionnelles traité par les types sous-jacents
CWG 2226 C++11 lors de la détermination du type cible de l'autre
opérande d'un opérateur conditionnel, la référence ne
pouvait pas se lier à une xvalue si cet opérande est une lvalue
autorisé
CWG 2283 C++17 l'exigence de complétude de type pour l'opérateur d'appel
de fonction a été accidentellement supprimée par P0135R1
rétabli l'exigence
CWG 2321 C++98 lors de la détermination du type cible de l'autre opérande
d'un opérateur conditionnel, un type de classe dérivée ne
pouvait pas être converti en un type de classe de base moins qualifié cv
autorisé à convertir vers le type
de classe de base avec la qualification cv
de l'opérande de classe dérivée
CWG 2715 C++98 l'initialisation et la destruction de chaque
paramètre se produiraient dans le contexte de
la fonction appelante, qui pourrait ne pas exister [1]
se produit dans le contexte de
l'expression complète englobante
CWG 2850 C++98 l'ordre de destruction des paramètres n'était pas clair clarifié
CWG 2865 C++98 si TX et TY sont le même type de classe et TX est
plus qualifié cv que TY , une séquence de conversion
implicite pouvait encore être formée à partir d'une prvalue Y
aucune séquence de conversion
ne sera formée dans ce cas
CWG 2906 C++98 les conversions lvalue-vers-rvalue étaient appliquées
inconditionnellement dans le cas de résultat rvalue pour l'opérateur conditionnel
appliquées seulement dans certains cas
  1. Par exemple, les fonctions peuvent être appelées dans l'initialiseur d'une variable de portée de namespace, il n'y a pas de « fonction appelante » dans ce contexte.

Voir aussi

Priorité des opérateurs
Surcharge des opérateurs

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

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 cv -qualificateurs
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 Autres opérateurs