Namespaces
Variants

Expressions

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Выражение — это последовательность операторов и их операндов , которая определяет вычисление.

Вычисление выражения может производить результат (например, вычисление 2 + 2 даёт результат 4 ) и может вызывать побочные эффекты (например, вычисление std:: printf ( "%d" , 4 ) выводит символ '4' на стандартный вывод).

Каждое выражение в C++ характеризуется двумя независимыми свойствами: типом и категорией значения.

Содержание

Общее

Операторы

Общие операторы
присваивание инкремент
декремент
арифметические логические сравнения доступа к членам
класса
прочие

a = b
a + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b
a <=> b

a [ ... ]
* a
& a
a - > b
a. b
a - > * b
a. * b

вызов функции

a ( ... )
запятая

a, b
условный оператор

a ? b : c
Специальные операторы

static_cast преобразует один тип в другой связанный тип
dynamic_cast преобразует в пределах иерархий наследования
const_cast добавляет или удаляет cv -квалификаторы
reinterpret_cast преобразует тип в несвязанный тип
C-style приведение преобразует один тип в другой с помощью комбинации static_cast , const_cast и reinterpret_cast
new создает объекты с динамической продолжительностью хранения
delete уничтожает объекты, ранее созданные выражением new, и освобождает полученную область памяти
sizeof запрашивает размер типа
sizeof... запрашивает размер пакета (since C++11)
typeid запрашивает информацию о типе
noexcept проверяет, может ли выражение генерировать исключение (since C++11)
alignof запрашивает требования к выравниванию типа (since C++11)

Преобразования

Выделение памяти

Другое

Первичные выражения

Операндами любого оператора могут быть другие выражения или первичные выражения (например, в 1 + 2 * 3 операндами operator+ являются подвыражение 2 * 3 и первичное выражение 1 ).

Первичные выражения — это любое из следующего:

(начиная с C++26)
(начиная с C++11)
(начиная с C++17)
(начиная с C++20)

Любое выражение в скобках также классифицируется как первичное выражение: это гарантирует, что скобки имеют более высокий приоритет, чем любой оператор. Скобки сохраняют значение, тип и категорию значения.

Литералы

Литералы — это токены программы на C++, которые представляют постоянные значения, встроенные в исходный код.

  • char или wchar_t
  • char16_t или char32_t
(начиная с C++11)
  • char8_t
(начиная с C++20)
  • const char [ ] или const wchar_t [ ]
  • const char16_t [ ] или const char32_t [ ]
(начиная с C++11)
  • const char8_t [ ]
(начиная с C++20)
  • nullptr является указательным литералом, который задает значение нулевого указателя
  • пользовательские литералы являются константными значениями пользовательского типа
(начиная с C++11)

Полные выражения

Составное выражение определяется следующим образом:

  • Составное выражение выражения — это само это выражение.
  • Составные выражения списка инициализации в фигурных скобках или (возможно, заключенного в круглые скобки) списка выражений — это составные выражения элементов соответствующего списка.
  • Составные выражения инициализатора , который начинается с = , являются составными выражениями initializer-clause .
int num1 = 0;
num1 += 1; // Случай 1: составное выражение "num += 1" — это "num += 1"
int arr2[2] = {2, 22} // Случай 2: составные выражения
                      //         "{2, 22}" — это "2" и "22"
                      // Случай 3: составные выражения "= {2, 22}"
                      //         — это составные выражения "{2, 22}"
                      //         (т.е. также "2" и "22")

Непосредственные подвыражения выражения E это

  • составные выражения E операндов,
(since C++14)
  • если E является лямбда-выражением , инициализация сущностей, захваченных по значению, и составные выражения инициализатора захватов,
(since C++11)
  • любой вызов функции, который E неявно вызывает, или
  • если E является вызовом функции или неявно вызывает функцию, составные выражения каждого аргумента по умолчанию используемого в вызове.

Подвыражение выражения E является непосредственным подвыражением E или подвыражением непосредственного подвыражения E . Обратите внимание, что выражения, появляющиеся в «теле функции» лямбда-выражений, не являются подвыражениями лямбда-выражения. (начиная с C++11)

Следующие выражения являются полными выражениями  :

(начиная с C++20)
(начиная с C++26)
  • выражения, которые не являются подвыражением какого-либо другого выражения и не входят в состав какого-либо полного выражения

Если языковая конструкция определена как производящая неявный вызов функции, использование этой языковой конструкции считается выражением для целей данного определения. Преобразования, применяемые к результату выражения для удовлетворения требований языковой конструкции, в которой это выражение присутствует, также считаются частью полного выражения.

Для инициализатора выполнение инициализации сущности (включая вычисление инициализаторов по умолчанию для членов агрегата) (начиная с C++14) также считается частью полного выражения.

Потенциально вычисляемые выражения

Выражение является потенциально вычисляемым за исключением случаев, когда

  • оно является операндом оператора sizeof , или
  • оно является операндом оператора typeid и не обозначает lvalue полиморфного типа класса.
(до C++11)

Следующие операнды являются невычисляемыми операндами , они не вычисляются:

  • выражения, к которым применяется оператор typeid , за исключением glvalue полиморфных типов классов
  • выражения, которые являются операндами оператора sizeof
  • операнды оператора noexcept
  • операнды спецификатора decltype
  • constraint-expression определений концептов
  • выражения, следующие за ключевым словом requires в requires clauses
  • выражения, появляющиеся в requirement-seq выражений requires
(начиная с C++20)

Выражение является потенциально вычисляемым за исключением случаев, когда

  • оно является невычисляемым операндом, или
  • оно является подвыражением невычисляемого операнда.
(начиная с C++11)

Потенциально вычисляемые выражения являются ODR-использованием .

Выражения с отбрасываемым значением

Отбрасываемое выражение — это выражение, которое используется только для его побочных эффектов. Значение, вычисляемое таким выражением, отбрасывается. К таким выражениям относятся полное выражение любого выражения-оператора , левый операнд встроенного оператора запятая или операнд приведения типа, которое приводится к типу void .

Преобразования массива в указатель и функции в указатель никогда не применяются к значению, вычисляемому выражением отброшенного значения. Преобразование lvalue в rvalue применяется тогда и только тогда, когда выражение является volatile-квалифицированным glvalue и имеет одну из следующих форм (требуется встроенное значение, возможно в скобках):

  • id-expression,
  • array subscript expression,
  • class member access expression,
  • indirection,
  • 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.

Кроме того, если lvalue имеет тип класса с квалификатором volatile, для инициализации результирующего временного объекта rvalue требуется конструктор копирования с квалификатором volatile.

Если выражение является prvalue не-void типа (после любого преобразования lvalue-to-rvalue, которое могло произойти), происходит материализация временного объекта .

Компиляторы могут выдавать предупреждения, когда выражение, отличное от приведения к void , отбрасывает значение, объявленное с [[ nodiscard ]] .

(начиная с C++17)

Эквивалентность выражений

Несколько выражений e1 , e2 , ..., eN являются эквивалентными выражениями если выполняются все следующие условия:

  1. Они имеют одинаковые эффекты.
  2. Либо все они являются константными подвыражениями либо ни одно из них не является.
  3. Либо все они являются noexcept либо ни одно из них не является.

e1 является эквивалентным выражению e2 тогда и только тогда, когда e1 и e2 являются эквивалентными выражениями (что означает e2 также является эквивалентным выражению e1 ).

(начиная с C++20)

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, являющиеся дефектными, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
CWG 1054 C++98 присваивание значения volatile переменной может
приводить к избыточному чтению из-за преобразования
lvalue-to-rvalue, применяемого к результату присваивания
ввести discarded-value выражения
и исключить этот случай из списка
случаев, требующих преобразование
CWG 1343 C++98 порядок вызовов деструкторов при
агрегатной инициализации был недостаточно специфицирован
full-expression в агрегатной инициализации
четко специфицированы
CWG 1383 C++98 список выражений, где преобразование lvalue-to-rvalue
применяется к discarded-value выражениям,
также включал перегруженные операторы
охватывать только операторы
со встроенным значением
CWG 1576 C++11 преобразования lvalue-to-rvalue не применялись
к discarded-value volatile xvalue выражениям
применять преобразование
в этом случае
CWG 2249 C++98 идентификаторы, объявляемые в деклараторах,
не являлись id-expression
являются
CWG 2431 C++11 вызовы деструкторов временных объектов,
которые связаны с ссылками, не являлись full-expression
являются

Смотрите также

Документация C для Выражения