This is a chart I combined from various sources online and from books. You can use it to better understand which operators C++ will apply before others whenever you have an expression containing multiple operators. Most other charts say that you can override the order with parenthesis. But they leave the parenthesis out of the precedence chart. This chart fixes that by including parenthesis together with lambda syntax in the highest group.
This chart also goes into more detail than you might find elsewhere. For example, the scope resolution operator is listed here in multiple forms. Some of the information here is my interpretation. So if you find something that you don’t understand, let me know with a comment. Thanks.
C++ Operator Precedence |
||||
Operator |
Name |
Use |
Overloadable |
Arity |
Group 1: no associativity (highest precedence) |
||||
( ) |
parenthesized expression |
(expr) |
no |
n/a |
[ ] { } |
lambda |
[capture-list] lambda-declaration {statement-list} |
no |
n/a |
Group 2: no associativity |
||||
:: |
global scope |
::name |
no |
unary |
:: |
class scope |
class::member |
no |
binary |
:: |
namespace scope |
namespace::member |
no |
binary |
Group 3: left-to-right associativity |
||||
. |
direct member selection |
object.member |
no |
binary |
-> |
indirect member selection |
pointer->member |
yes |
binary |
[ ] |
subscript |
pointer [expr] object [expr] |
yes |
binary |
( ) |
function call |
expr (expr-list) |
yes |
n/a |
( ) |
initialization |
type (expr-list) |
no (constructor) |
n/a |
{ } |
uniform initialization |
type {expr-list} |
no (constructor) |
n/a |
type ( ) |
functional cast |
type (expr) |
no (operator) |
n/a |
type { } |
functional cast |
type {expr} |
no (operator) |
n/a |
++ |
post increment |
lvalue++ |
yes |
unary |
– – |
post decrement |
lvalue– |
yes |
unary |
typeid ( ) |
type identification |
typeid (type) |
no |
n/a |
typeid ( ) |
run-time type identification |
typeid (expr) |
no |
n/a |
dynamic_cast |
run-time checked conversion |
dynamic_cast<type> (expr) |
no |
n/a |
static_cast |
compile-time checked conversion |
static_cast<type> (expr) |
no (operator) |
n/a |
reinterpret_cast |
unchecked conversion |
reinterpret_cast<type> (expr) |
no |
n/a |
const_cast |
const conversion |
const_cast<type> (expr) |
no |
n/a |
dynamic_pointer_cast |
run-time checked conversion |
dynamic_pointer_cast<type> (shrptr) |
no |
n/a |
static_pointer_cast |
compile-time checked conversion |
static_pointer_cast<type> (shrptr) |
no |
n/a |
reinterpret_pointer_cast |
unchecked conversion |
reinterpret_pointer_cast<type> (shrptr) |
no |
n/a |
const_pointer_cast |
const conversion |
const_pointer_cast<type> (shrptr) |
no |
n/a |
Group 4: right-to-left associativity |
||||
sizeof |
size of object |
sizeof expr |
no |
unary |
sizeof ( ) |
size of type |
sizeof (type) |
no |
unary |
sizeof… |
size of parameter pack |
sizeof… name |
no |
unary |
alignof ( ) |
alignment of type |
alignof (type) |
no |
unary |
++ |
pre increment |
++lvalue |
yes |
unary |
– – |
pre decrement |
– -lvalue |
yes |
unary |
~ compl |
bitwise complement |
~expr compl expr |
yes |
unary |
! not |
logical not |
!expr not expr |
yes |
unary |
– |
unary minus |
-expr |
yes |
unary |
+ |
unary plus |
+expr |
yes |
unary |
* |
dereference |
*expr |
yes |
unary |
& |
address-of |
&lvalue |
yes (not recommended) |
unary |
(type) |
type conversion |
(type) expr |
no (operator) |
n/a |
new |
allocate object |
new type |
yes |
n/a |
new ( ) |
allocate object and initialize |
new type (expr-list) |
yes |
n/a |
new { } |
allocate object and initialize |
new type {expr-list} |
yes |
n/a |
new ( ) |
allocate object in-place |
new (expr-list) type |
yes |
n/a |
new ( ) ( ) |
allocate object in-place and initialize |
new (expr-list) type (expr-list) |
yes |
n/a |
new ( ) { } |
allocate object in-place and initialize |
new (expr-list) type {expr-list} |
yes |
n/a |
new [ ] |
allocate array |
new type [size] |
yes |
n/a |
delete |
deallocate object |
delete pointer |
yes |
n/a |
delete [ ] |
deallocate array |
delete [ ] pointer |
yes |
n/a |
noexcept ( ) |
can expression throw |
noexcept (expr) |
no |
n/a |
Group 5: left-to-right associativity |
||||
.* |
direct pointer to member selection |
object.*pointer-to-member |
no |
binary |
->* |
indirect pointer to member selection |
pointer->*pointer-to-member |
yes |
binary |
Group 6: left-to-right associativity |
||||
* |
multiplication |
expr * expr |
yes |
binary |
/ |
dividision |
expr / expr |
yes |
binary |
% |
modulo (remainder) |
expr % expr |
yes |
binary |
Group 7: left-to-right associativity |
||||
+ |
addition |
expr + expr |
yes |
binary |
– |
subtraction |
expr – expr |
yes |
binary |
Group 8: left-to-right associativity |
||||
<< |
bitwise left shift |
expr << expr |
yes |
binary |
>> |
bitwise right shift |
expr >> expr |
yes |
binary |
Group 9: left-to-right associativity |
||||
< |
less than |
expr < expr |
yes |
binary |
<= |
less than or equal |
expr <= expr |
yes |
binary |
> |
greater than |
expr > expr |
yes |
binary |
>= |
greater than or equal |
expr >= expr |
yes |
binary |
Group 10: left-to-right associativity |
||||
== |
equal |
expr == expr |
yes |
binary |
!= not_eq |
not equal |
expr != expr expr not_eq expr |
yes |
binary |
Group 11: left-to-right associativity |
||||
& bitand |
bitwise and |
expr & expr expr bitand expr |
yes |
binary |
Group 12: left-to-right associativity |
||||
^ xor |
bitwise exclusive or |
expr ^ expr expr xor expr |
yes |
binary |
Group 13: left-to-right associativity |
||||
| bitor |
bitwise or |
expr | expr expr bitor expr |
yes |
binary |
Group 14: left-to-right associativity |
||||
&& and |
logical and |
expr && expr expr and expr |
yes |
binary |
Group 15: left-to-right associativity |
||||
|| or |
logical or |
expr || expr expr or expr |
yes |
binary |
Group 16: right-to-left associativity |
||||
? : |
conditional |
expr ? expr : conditional-expr expr ? expr : assignment-expr |
no |
ternary |
Group 17: right-to-left associativity |
||||
{ } |
list |
{expr-list} |
no |
n/a |
= |
assignment |
lvalue = expr |
yes |
binary |
*= |
multiplication assignment |
lvalue *= expr |
yes |
binary |
/= |
division assignment |
lvalue /= expr |
yes |
binary |
%= |
modulo assignment |
lvalue %= expr |
yes |
binary |
+= |
addition assignment |
lvalue += expr |
yes |
binary |
-= |
subtraction assignment |
lvalue -= expr |
yes |
binary |
<<= |
bitwise left shift assignment |
lvalue <<= expr |
yes |
binary |
>>= |
bitwise right shift assignment |
lvalue >>= expr |
yes |
binary |
&= and_eq |
bitwise and assignment |
lvalue &= expr lvalue and_eq expr |
yes |
binary |
|= or_eq |
bitwise or assignment |
lvalue |= expr lvalue or_eq expr |
yes |
binary |
^= xor_eq |
bitwise exclusive or assignment |
lvalue ^= expr lvalue xor_eq expr |
yes |
binary |
Group 18: right-to-left associativity |
||||
throw |
throw exception |
throw expr |
no |
unary |
Group 19: left-to-right associativity (lowest precedence) |
||||
, |
comma |
expr, expr |
yes (not recommended) |
binary |
Wahid this is the most detailed precedence and associativity table I have seen.