An expression is a sequence of operators and their operands, that specifies a computation.
Expression evaluation may produce a result (e.g., evaluation of 2+2 produces the result 4) and may generate side-effects (e.g. evaluation of std::printf("%d",4) prints the character '4' on the standard output).
- value categories (lvalue, rvalue, glvalue, prvalue, xvalue) classify expressions by their values
- order of evaluation of arguments and subexpressions specify the order in which intermediate results are obtained
| Common operators
a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b
a + b
a - b
a * b
a / b
a % b
a & b
a | b
a ^ b
a << b
a >> b
a && b
a || b
a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b
| Special operators
static_cast converts one type to another related type
dynamic_cast converts within inheritance hierarchies
const_cast adds or removes cv qualifiers
reinterpret_cast converts type to unrelated type
C-style cast converts one type to another by a mix of
new creates objects with dynamic storage duration
delete destructs objects previously created by the new expression and releases obtained memory area
sizeof queries the size of a type
sizeof... queries the size of a parameter pack (since C++11)
typeid queries the type information of a type
noexcept checks if an expression can throw an exception (since C++11)
alignof queries alignment requirements of a type (since C++11)
The operands of any operator may be other expressions or primary expressions (e.g. in 1+2*3, the operands of operator+ are the subexpression 2*3 and the primary expression 1).
Primary expressions are any of the following:
1) Literals (e.g. 2 or "Hello, world")
Any expression in parentheses is also classified as a primary expression: this guarantees that the parentheses have higher precedence than any operator. Parentheses preserve value, type, and value category.
Literals are the tokens of a C++ program that represent constant values embedded in the source code.
- integer literals are decimal, octal, hexadecimal or binary numbers of integer type.
- character literals are individual characters of type char, char16_t, char32_t, or wchar_t
- floating-point literals are values of type float, double, or long double
- string literals are sequences of characters of type const char, const char16_t, const char32_t, or const wchar_t
- boolean literals are values of type bool, that is true and false
- nullptr is the pointer literal which specifies a null pointer value (since C++11)
- user-defined literals are constant values of user-specified type (since C++11)
The operands of the operators typeid, sizeof, noexcept, and decltype (since C++11) are expressions that are not evaluated (unless they are polymorphic glvalues and are the operands of
typeid), since these operators only query the compile-time properties of their operands. Thus, std::size_t n = sizeof(std::cout << 42); does not perform console output.
The unevaluated operands are considered to be full expressions even though they are syntactically operands in a larger expression (for example, this means that sizeof(T()) requires an accessible
A discarded-value expression is an expression that is used for its side-effects only. The value calculated from such expression is discarded. Such expressions include the full expression of any expression statement, the left-hand argument of the built-in comma operator, or the argument of a cast-expression that casts to the type void.
Array-to-pointer and function-to-pointer conversions are never applied to the value calculated by a discarded-value expression. The lvalue-to-rvalue conversion, however, is applied, but only if the expression is a volatile-qualified glvalue and has one of the following forms (possibly parenthesized)
- array subscript expression
- class member access expression
- pointer-to-member operation
- conditional expression where both the second and the third operands are one of these expressions,
- comma expression where the right operand is one of these expressions.
In addition, if the expression is of class type, a volatile copy-constructor is required to initialize the resulting rvalue temporary.
If the expression is a prvalue (after any lvalue-to-rvalue conversion that might have taken place), temporary materialization occurs. If the original glvalue is of volatile-qualified class type, a volatile copy-constructor is required to initialize the resulting rvalue temporary.
Compilers may issue warnings when an expression other than cast to
void discards a value declared