Arithmetic operators
Returns the result of specific arithmetic operation.
Operator name | Syntax | Overloadable | Prototype examples (for class T) | |
---|---|---|---|---|
Inside class definition | Outside class definition | |||
unary plus | +a | Yes | T T::operator+() const; | T operator+(const T &a); |
unary minus | -a | Yes | T T::operator-() const; | T operator-(const T &a); |
addition | a + b | Yes | T T::operator+(const T2 &b) const; | T operator+(const T &a, const T2 &b); |
subtraction | a - b | Yes | T T::operator-(const T2 &b) const; | T operator-(const T &a, const T2 &b); |
multiplication | a * b | Yes | T T::operator*(const T2 &b) const; | T operator*(const T &a, const T2 &b); |
division | a / b | Yes | T T::operator/(const T2 &b) const; | T operator/(const T &a, const T2 &b); |
modulo | a % b | Yes | T T::operator%(const T2 &b) const; | T operator%(const T &a, const T2 &b); |
bitwise NOT | ~a | Yes | T T::operator~() const; | T operator~(const T &a); |
bitwise AND | a & b | Yes | T T::operator&(const T2 &b) const; | T operator&(const T &a, const T2 &b); |
bitwise OR | a | b | Yes | T T::operator|(const T2 &b) const; | T operator|(const T &a, const T2 &b); |
bitwise XOR | a ^ b | Yes | T T::operator^(const T2 &b) const; | T operator^(const T &a, const T2 &b); |
bitwise left shift | a << b | Yes | T T::operator<<(const T2 &b) const; | T operator<<(const T &a, const T2 &b); |
bitwise right shift | a >> b | Yes | T T::operator>>(const T2 &b) const; | T operator>>(const T &a, const T2 &b); |
|
Contents |
[edit] Explanation
All arithmetic operators compute the result of specific arithmetic operation and returns its result. The arguments are not modified.
[edit] Conversions
If the operand passed to an arithmetic operator is integral or unscoped enumeration type, then before any other action (but after lvalue-to-rvalue conversion, if applicable), the operand undergoes integral promotion. If an operand has array or function type, array-to-pointer and function-to-pointer conversions are applied.
For the binary operators (except shifts), if the promoted operands have different types, additional set of implicit conversions is applied, known as usual arithmetic conversions with the goal to produce the common type (also accessible via the std::common_type type trait)
- If either operand has scoped enumeration type, no conversion is performed: the other operand and the return type must have the same type
- Otherwise, if either operand is long double, the other operand is converted to long double
- Otherwise, if either operand is double, the other operand is converted to double
- Otherwise, if either operand is float, the other operand is converted to float
- Otherwise, the operand has integer type (because bool, char, char16_t, char32_t, wchar_t, and unscoped enumeration were promoted at this point) and integral conversions are applied to produce the common type, as follows:
- If both operands are signed or both are unsigned, the operand with lesser conversion rank is converted to the operand with the greater integer conversion rank
- Otherwise, if the unsigned operand's conversion rank is greater or equal to the conversion rank of the signed operand, the signed operand is converted to the unsigned operand's type.
- Otherwise, if the signed operand's type can represent all values of the unsigned operand, the unsigned operand is converted to the signer operand's type
- Otherwise, both operands are converted to the unsigned counterpart of the signed operand's type.
The conversion rank above increases in order bool, signed char, short, int, long, long long. The rank of any unsigned type is equal to the rank of the corresponding signed type. The rank of char is equal to the rank of signed char and unsigned char. The ranks of char16_t, char32_t, and wchar_t are equal to the ranks of their underlying types.
[edit] Unary arithmetic operators
For every promoted arithmetic type A and for every type T, the following function signatures participate in overload resolution:
A operator+(A) |
||
T* operator+(T*) |
||
A operator-(A) |
||
The builtin unary plus operator returns the value of its operand. The only situation where it is not a no-op is when the operand has integral type or unscoped enumeration type, which is changed by integral promotion, e.g, it converts char to int or if the operand is subject to lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversion.
The builtin unary minus operator calculates the negative of its operand. For unsigned a, the value of -a is 2b
-a, where b is the number of bits after promotion.
#include <iostream> int main() { char c = 0x6a; int n1 = 1; unsigned char n2 = 1; unsigned int n3 = 1; std::cout << "char: " << c << " int: " << +c << '\n' << "-1, where 1 is signed: " << -n1 << '\n' << "-1, where 1 is unsigned char: " << -n2 << '\n' << "-1, where 1 is unsigned int: " << -n3 << '\n'; char a[3]; std::cout << "size of array: " << sizeof a << '\n' << "size of pointer: " << sizeof +a << '\n'; }
Output:
char: j int: 106 -1, where 1 is signed: -1 -1, where 1 is unsigned char: -1 -1, where 1 is unsigned int: 4294967295 size of array: 3 size of pointer: 8
[edit] Additive operators
For every pair of promoted arithmetic types L and R and for every object type T, the following function signatures participate in overload resolution:
LR operator+(L, R) |
||
LR operator-(L, R) |
||
T* operator+(T*, std::ptrdiff_t) |
||
T* operator+(std::ptrdiff_t, T*) |
||
T* operator-(T*, std::ptrdiff_t) |
||
std::ptrdiff_t operator-(T*, T*) |
||
where LR is the result of usual arithmetic conversions on L and R
With operands of arithmetic or enumeration type, the result of binary plus is the sum of the operands (after usual arithmetic converesions), and the result of the binary minus operator is the result of subtracting the second operand from the first (after usual arithmetic conversions).
If any of the operands is a pointer, the following rules apply:
- A pointer to non-array object is treated as a pointer to the first element of an array with size 1.
- If the pointer P points to the ith element of an array, then the expressions P+n, n+P, and P-n are pointers of the same type that point to the i+nth, i+nth, and i-nth element of the same array, respectively. The result of pointer addition may also be a one-past-the-end pointer (that is, pointer P such that the expression P-1 points to the last element of the array). Any other situations (that is, attempts to generate a pointer that isn't pointing at an element of the same array or one past the end) invoke undefined behavior.
- If the pointer P points to the ith element of an array, and the pointer Q points at the jth element of the same array, the expression P-Q has the value i-j, if the value fits in std::ptrdiff_t. Both operands must point to the elements of the same array (or one past the end), otherwise the behavior is undefined. If the result does not fit in std::ptrdiff_t, the behavior is undefined.
- If the value 0 is added or subtracted from a pointer, the result is the pointer, unchanged. If two pointers point at the same object or are both one past the end of the same array, or both are null pointers, then the result of subtraction is equal to (std::ptrdiff_t)0.
These pointer arithmetic operators allow pointers to satisfy the RandomAccessIterator concept.
#include <iostream> int main() { char c = 2; unsigned int un = 2; int n = -10; std::cout << " 2 + (-10), where 2 is a char = " << c + n << '\n' << " 2 + (-10), where 2 is unsigned = " << un + n << '\n' << " -10 - 2.12 = " << n - 2.12 << '\n'; char a[4] = {'a', 'b', 'c', 'd'}; char* p = &a[1]; std::cout << "Pointer addition examples: " << *p << *(p + 2) << *(2 + p) << *(p - 1) << '\n'; char* p2 = &a[4]; std::cout << "Pointer difference: " << p2 - p << '\n'; }
Output:
2 + (-10), where 2 is a char = -8 2 + (-10), where 2 is unsigned = 4294967288 -10 - 2.12 = -12.12 Pointer addition examples: bdda Pointer difference: 3
[edit] Multiplicative operators
For every pair of promoted arithmetic types LA and RA and for every pair of promoted integral types LI and RI the following function signatures participate in overload resolution:
LRA operator*(LA, RA) |
||
LRA operator/(LA, RA) |
||
LRI operator%(LI, RI) |
||
where LRx is the result of usual arithmetic conversions on Lx and Rx
The binary operator * performs multiplication of its operands (after usual arithmetic conversions).
The binary operator / divides the first operand by the second (after usual arithmetic conversions).If the second operand is zero, the behavior is undefined. For integral operands, it yields the algebraic quotient
- rounded in implementation-defined direction (until C++11)
- with any fractional part discarded (truncated towards zero) (since C++11)
The binary operator % yields the remainder of the division of the first operand by the second (after usual arithmetic conversions). If the quotient a/b is representible in the result type, (a/b)*b + a%b == a. If the second operand is zero, the behavior is undefined.
- if one or both operands are negative, the sign of the remainder is implementation-defined, as it depends on the rounding direction of integer division (until C++11)
#include <iostream> int main() { char c = 2; unsigned int un = 2; int n = -10; std::cout << "2 * (-10), where 2 is a char = " << c * n << '\n' << "2 * (-10), where 2 is unsigned = " << un * n << '\n' << "-10 / 2.12 = " << n / 2.12 << '\n' << "-10 / 21 = " << n / 21 << '\n' << "-10 % 21 = " << n % 21 << '\n'; }
Output:
2 * (-10), where 2 is a char = -20 2 * (-10), where 2 is unsigned = 4294967276 -10 / 2.12 = -4.71698 -10 / 21 = 0 -10 % 21 = -10
[edit] Bitwise logic operators
For every pair of promoted integral types L and R the following function signatures participate in overload resolution:
R operator~(R) |
||
LR operator&(L, R) |
||
LR operator^(L, R) |
||
LR operator|(L, R) |
||
where LR is the result of usual arithmetic conversions on L and R
The result of operator~ is the bitwise NOT (one's complement) value of the argument (after promotion). The result of operator& is the bitwise AND value of the operands (after usual arithmetic conversions). The result of operator| is the bitwise OR value of the operands (after usual arithmetic conversions). The result of operator^ is the bitwise XOR value of the operands (after usual arithmetic conversions)
#include <iostream> int main() { std::cout << std::hex << std::showbase; uint16_t mask = 0x00f0; uint32_t a = 0x12345678; std::cout << "Value: " << a << " mask: " << mask << '\n' << "Setting bits: " << (a
Output:
Value: 0x12345678 mask: 0xf0 Setting bits: 0x123456f8 Clearing bits: 0x12345608 Selecting bits: 0x70
[edit] Bitwise shift operators
For every pair of promoted integral types L and R, the following function signatures participate in overload resolution:
L operator<<(L, R) |
||
L operator>>(L, R) |
||
The operands of the built-in bitwise shift operators have either integral types or unscoped enumeration type. Integral promotions are performed on both operands before evaluation. The return type is the type of the left operand after integal promotions.
For unsigned a, the value of a << b is the value of a * 2b
, reduced modulo maximum value of the return type plus 1 (that is, bitwise left shift is performed and the bits that get shifted out of the destination type are discarded). For signed a, the value of a << b is a * 2b
if it is representable by the return type, otherwise the behavior is undefined.
For unsigned a and for signed a with nonnegative values, the value of a >> b is the integer part of a/2b
. For negative a, the value of a >> b is implementation-defined (in most implementations, this performs arithmetic right shift, so that the result remains negative)
In any case, if the value of the right operand is negative or is greater or equal to the number of bits in the promoted left operand, the behavior is undefined.
#include <iostream> enum {ONE=1, TWO=2}; int main() { std::cout << std::hex << std::showbase; char c = 0x10; unsigned long long ull = 0x123; std::cout << "0x123 << 1 = " << (ull << 1) << '\n' << "0x123 << 63 = " << (ull << 63) << '\n' // overflow in unsigned << "0x10 << 10 = " << (c << 10) << '\n'; // char is promoted to int long long ll = -1000; std::cout << std::dec << "-1000 >> 1 = " << (ll >> ONE) << '\n'; }
Output:
0x123 << 1 = 0x246 0x123 << 63 = 0x8000000000000000 0x10 << 10 = 0x4000 -1000 >> 1 = -500
[edit] Standard library
Arithmetic operators are overloaded for many standard library types.
[edit] Unary arithmetic operators
implements unary + and unary - (public member function of std::chrono::duration) | |
applies unary operators to complex numbers (function template) | |
applies a unary arithmetic operator to each element of the valarray (public member function of std::valarray) |
[edit] Additive operators
implements arithmetic operations with durations as arguments (function template) | |
modifies the time point by the given duration (function template) | |
concatenates two strings or a string and a char (function template) | |
advances the iterator (public member function of std::reverse_iterator) | |
decrements the iterator (public member function of std::reverse_iterator) | |
advances the iterator (public member function of std::move_iterator) | |
decrements the iterator (public member function of std::move_iterator) | |
performs complex number arithmetics on two complex values or a complex and a scalar (function template) | |
applies binary operators to each element of two valarrays, or a valarray and a value (function template) |
[edit] Multiplicative operators
implements arithmetic operations with durations as arguments (function template) | |
performs complex number arithmetics on two complex values or a complex and a scalar (function template) | |
applies binary operators to each element of two valarrays, or a valarray and a value (function template) |
[edit] Bitwise logic operators
performs binary NOT (public member function of std::bitset) | |
performs binary logic operations on bitsets (function) | |
applies a unary arithmetic operator to each element of the valarray (public member function of std::valarray) | |
applies binary operators to each element of two valarrays, or a valarray and a value (function template) |
[edit] Bitwise shift operators
applies binary operators to each element of two valarrays, or a valarray and a value (function template) | |
performs binary shift left and shift right (public member function of std::bitset) |
[edit] Stream insertion/extraction operators
Throughout the standard library, bitwise shift operators are commonly overloaded with I/O stream (std::ios_base& or one of the classes derived from it) as both the left operand and return type. Such operators are known as stream insertion and stream extraction operators:
extracts formatted data (public member function of std::basic_istream) | |
extracts characters and character arrays (function template) | |
inserts formatted data (public member function of std::basic_ostream) | |
inserts character data (function) | |
serializes and deserializes a complex number (function template) | |
performs stream input and output of bitsets (function) | |
performs stream I/O on strings (function template) | |
performs stream input and output on pseudo-random number engine (function) | |
performs stream input and output on pseudo-random number distribution (function) |
[edit] See also
Common operators | ||||||
---|---|---|---|---|---|---|
assignment | increment decrement |
arithmetic | logical | comparison | member access |
other |
a = b |
++a |
+a |
!a |
a == b |
a[b] |
a(...) |
Special operators | ||||||
static_cast converts one type to another compatible type |