The following table lists the precedence and associativity of C++ operators. Operators are listed top to bottom, in descending precedence. a, b and c are operands.
Precedence Operator Description Associativity 1 a::b
Left-to-right → 2 a++a--Suffix/postfix
type(a)type{a}
a()
a[]
a.ba->b
3 ++a--aPrefix
Right-to-left ← +a-aUnary
!a~a
and
(type)a
*a
(dereference) &a
^^a
(since C++26)
(C++20)
–
–
4 a.*ba->*b
Left-to-right → 5 a*ba/ba%b
Multiplication, division, and remainder
6 a+ba-b
7 a<<ba>>bBitwise
8 a<=>b
(since C++20)9 a<ba<=ba>ba>=bFor
< and <= and > and >= respectively 10 a==ba!=bFor
= and != respectively 11 a&b
12 a^b
(exclusive or) 13 a|b
(inclusive or) 14 a&&b
15 a||b
16 a?b:c
Right-to-left ←
(C++20)a=b
(provided by default for C++ classes) a+=ba-=b
by sum and difference a*=ba/=ba%=b
by product, quotient, and remainder a<<=ba>>=b
by bitwise left shift and right shift a&=ba^=ba|=b
by bitwise AND, XOR, and OR 17 a,b
Left-to-right →
The operand of sizeof cannot be a C-style type cast: the expression sizeof(int)*p is unambiguously interpreted as (sizeof(int))*p, but not sizeof((int)*p).
The expression in the middle of the conditional operator (between ? and :) is parsed as if parenthesized: its precedence relative to ?: is ignored.
When parsing an expression, an operator which is listed on some row of the table above with a precedence will be bound tighter (as if by parentheses) to its arguments than any operator that is listed on a row further below it with a lower precedence. For example, the expressions std::cout<<a&b and *p++ are parsed as (std::cout<<a)&b and *(p++), and not as std::cout<<(a&b) or (*p)++.
Operators that have the same precedence are bound to their arguments in the direction of their associativity. For example, the expression a=b=c is parsed as a=(b=c), and not as (a=b)=c because of right-to-left associativity of assignment, but a+b-c is parsed (a+b)-c and not a+(b-c) because of left-to-right associativity of addition and subtraction.
Associativity specification is redundant for unary operators and is only shown for completeness: unary prefix operators always associate right-to-left (delete++*p is delete(++(*p))) and unary postfix operators always associate left-to-right (a[1][2]++ is ((a[1])[2])++). Note that the associativity is meaningful for member access operators, even though they are grouped with unary postfix operators: a.b++ is parsed (a.b)++ and not a.(b++).
Operator precedence is unaffected by
. For example, std::cout<<a?b:c; parses as (std::cout<<a)?b:c; because the precedence of arithmetic left shift is higher than the conditional operator.
Notes
Precedence and associativity are compile-time concepts and are independent from
, which is a runtime concept.
The standard itself doesn't specify precedence levels. They are derived from the grammar.
,
,
,
,
,
,
and
are not included since they are never ambiguous.
Some of the operators have
(e.g., and for &&, or for ||, not for !, etc.).
In C, the ternary conditional operator has higher precedence than assignment operators. Therefore, the expression e=a<d?a++:a=d, which is parsed in C++ as e=((a<d)?(a++):(a=d)), will fail to compile in C due to grammatical or semantic constraints in C. See the corresponding C page for details.
See also
Common operators
a=ba+=ba-=ba*=ba/=ba%=ba&=ba|=ba^=ba<<=ba>>=b++a--aa++a--+a-aa+ba-ba*ba/ba%b~aa&ba|ba^ba<<ba>>b!aa&&ba||ba==ba!=ba<ba>ba<=ba>=ba<=>ba[...]*a&aa->ba.ba->*ba.*bfunction calla(...)
commaa,b
conditionala?b:c
Special operators
converts one type to another related type
converts within inheritance hierarchies
adds or removes
-qualifiers
converts type to unrelated type
converts one type to another by a mix of static_cast, const_cast, and reinterpret_cast
creates objects with dynamic storage duration
destructs objects previously created by the new expression and releases obtained memory area
queries the size of a type
queries the size of a
(since C++11)
queries the type information of a type
checks if an expression can throw an exception (since C++11)
queries alignment requirements of a type (since C++11)
produces a reflection value from a grammatical construct (since C++26)