C++ operators behave like C's, with a few traps: integer division, precedence of bitwise ops, and implicit conversions between signed/unsigned and int/double.
Operator overview
| Kind | Operators | Notes |
|---|---|---|
| Arithmetic | + - * / % | int / int truncates toward zero; % takes the sign of the left operand |
| Increment | ++x, x++ | Prefix returns the new value (by reference); postfix returns a copy of the old one |
| Comparison | == != < <= > >=, <=> (C++20) | <=> (spaceship) returns an ordering |
| Logical | && || ! | Short-circuit evaluation |
| Bitwise | & | ^ ~ << >> | Lower precedence than == — parenthesise! |
| Assignment | = += -= *= /= %= &= |= ^= <<= >>= | Return a reference to the left side |
| Other | ?:, ,, sizeof, ::, ., ->, .*, ->* | :: is scope resolution |
#include <iostream>
int main() {
std::cout << 7 / 2 << ' ' << -7 / 2 << ' ' << 7 % 3 << ' ' << -7 % 3 << '\n';
int i = 5;
int a = i++; // a = 5, i = 6
int b = ++i; // i = 7, b = 7
std::cout << a << ' ' << b << ' ' << i << '\n';
int flags = 0b0110;
std::cout << ((flags & 0b0100) != 0) << ' ' << (flags | 1) << ' ' << (flags ^ 0b1111) << ' ' << (1 << 10) << '\n';
int x = 0;
bool ok = (x != 0) && (10 / x > 1); // short-circuit: division never runs
std::cout << std::boolalpha << ok << '\n';
}3 -3 1 -1
5 7 7
1 7 9 1024
falseImplicit conversions
Integral promotion:
char,short,boolare promoted tointin arithmetic.Usual arithmetic conversions: in
int + doubletheintbecomesdouble; inint + unsignedtheintbecomes unsigned.Narrowing:
double → inttruncates,long long → intmay lose bits — allowed with=, rejected with{}.
#include <iostream>
#include <vector>
int main() {
char c = 'A';
std::cout << c + 1 << ' ' << static_cast<char>(c + 1) << '\n'; // promoted to int
double d = 9.99;
int t = static_cast<int>(d); // truncates toward zero
std::cout << t << ' ' << static_cast<int>(-9.99) << '\n';
std::vector<int> v; // v.size() is unsigned
std::cout << v.size() - 1 << '\n'; // wraps: not -1!
std::cout << static_cast<long long>(v.size()) - 1 << '\n';
}66 B
9 -9
18446744073709551615
-1Explicit casts
| Cast | Use for |
|---|---|
static_cast<T>(x) | Ordinary, checked-at-compile-time conversions (numeric, up/down a class hierarchy without check) |
dynamic_cast<T>(x) | Safe down-casting of polymorphic types, checked at run time |
const_cast<T>(x) | Add/remove const (rarely legitimate) |
reinterpret_cast<T>(x) | Reinterpret bits/pointers (low-level, unsafe) |
(T)x / T(x) | C-style cast: tries all of the above — avoid, it hides intent |
See Casts & RTTI for the full story on the four named casts.
Evaluation order
What is the difference between ++i and i++?