Арифметические операторы
Возвращает результат выполнения конкретной арифметической операции.
| Имя оператора | Синтаксис | Перегружаемый | Примеры прототипов (для class T) | |
|---|---|---|---|---|
| Внутри определения класса | Вне определения класса | |||
| унарный плюс |
+a | Да |
T T::operator+() const; |
T operator+(const T &a); |
| унарный минус |
-a | Да |
T T::operator-() const; |
T operator-(const T &a); |
| сложение |
a + b | Да |
T T::operator+(const T2 &b) const; |
T operator+(const T &a, const T2 &b); |
| вычитание |
a - b | Да |
T T::operator-(const T2 &b) const; |
T operator-(const T &a, const T2 &b); |
| умножение |
a * b | Да |
T T::operator*(const T2 &b) const; |
T operator*(const T &a, const T2 &b); |
| деление |
a / b | Да |
T T::operator/(const T2 &b) const; |
T operator/(const T &a, const T2 &b); |
| остаток от деления |
a % b | Да |
T T::operator%(const T2 &b) const; |
T operator%(const T &a, const T2 &b); |
| битовый НЕ |
~a | Да |
T T::operator~() const; |
T operator~(const T &a); |
| битовый И |
a & b | Да |
T T::operator&(const T2 &b) const; |
T operator&(const T &a, const T2 &b); |
| битовый ИЛИ |
a | b | Да |
T T::operator|(const T2 &b) const; |
T operator|(const T &a, const T2 &b); |
| битовый ИСКЛЮЧАЮЩЕЕ ИЛИ |
a ^ b | Да |
T T::operator^(const T2 &b) const; |
T operator^(const T &a, const T2 &b); |
| сдвиг влево |
a << b | Да |
T T::operator<<(const T2 &b) const; |
T operator<<(const T &a, const T2 &b); |
| сдвиг вправо |
a >> b | Да |
T T::operator>>(const T2 &b) const; |
T operator>>(const T &a, const T2 &b); |
Примечания
|
||||
Общее объяснение
Все встроенные арифметические операторы вычисляют результат конкретной арифметической операции и возвращают его. Аргументы не изменяются.
Преобразования
Если операнд, переданный встроенному арифметическому оператору, имеет целочисленный или перечислимый тип, то перед любыми другими действиями (но после преобразования lvalue в rvalue, если применимо), операнд подвергается целочисленному продвижению. Если операнд имеет тип массива или функции, применяются преобразования массив в указатель и функция в указатель.
Для бинарных операторов (кроме сдвигов), если у продвинутых операндов разные типы, применяются обычные арифметические преобразования.
Переполнения
Арифметика целых без знака всегда выполняется по модулю 2n, где n — количество бит в этом целом числе. Например, для unsigned int добавление единицы к UINT_MAX дает 0, а вычитание единицы из 0 дает UINT_MAX.
При переполнении арифметической операции со знаком (результат не помещается в тип результата), поведение не определено — возможные проявления такой операции включают:
- циклический возврат по правилам представления (обычно дополнительный код),
- перехват — на некоторых платформах или из-за параметров компилятора (например,
-ftrapvв GCC и Clang), - насыщение до минимального или максимального значения (на многих DSP),
- полное исключение компилятором.
Окружение с плавающей запятой
Если #pragma STDC FENV_ACCESS поддерживается и установлено в ON, все арифметические операторы с плавающей запятой подчиняются текущему направлению округления с плавающей запятой и сообщают об ошибках арифметических операций с плавающей запятой, как указано в math_errhandling, за исключением случаев, когда они являются частью статической инициализации (в этом случае исключения с плавающей запятой не генерируются, а режим округления установлен на ближайшее значение).
Сжатие с плавающей запятой
Если #pragma STDC FP_CONTRACT поддерживается и установлено в OFF, вся арифметика с плавающей запятой может выполняться как если бы промежуточные результаты имели бесконечный диапазон и точность, то есть разрешены оптимизации, которые пропускают ошибки округления и исключения с плавающей запятой. Например, C++ позволяет реализацию (x * y) + z с одной инструкцией Fused Multiply-Add процессора или оптимизацию a = x * x * x * x; как tmp = x * x; a = tmp * tmp.
Независимо от сжатия, промежуточные результаты арифметических операций с плавающей запятой могут иметь диапазон и точность, отличные от указанных типом, см. FLT_EVAL_METHOD.
Формально стандарт C++ не гарантирует точность операций с плавающей запятой.
Унарные арифметические операторы
Выражения унарных арифметических операторов имеют вид
| +выражение | (1) | |
| -выражение | (2) |
Унарные операторы + и - имеют более высокий приоритет, чем все бинарные арифметические операторы, поэтому выражение не может содержать бинарные арифметические операторы верхнего уровня. Эти операторы ассоциируются справа налево:
+a - b; // equivalent to (+a) - b, NOT +(a - b)
-c + d; // equivalent to (-c) + d, NOT -(a + b)
+-e; // equivalent to +(-e), the unary + is a no-op if `e` is a built-in type
// because any possible promotion is performed during negationВстроенные унарные арифметические операторы
char преобразуется в int , а безгенерическая беззахватная лямбда-выражение преобразуется в указатель на функцию(с C++11) в выражениях унарного плюса.a, значение -a равно \({\small 2^N-a}\)2N-a, где N — количество бит после продвижения. - Иными словами, результат — это дополнительный код операнда (при этом операнд и результат рассматриваются как беззнаковые).
Перегрузки
В разрешении перегрузки для пользовательских операторов, для каждого cv-неквалифицированного продвинутого арифметического типа A и для каждого типа T, в разрешении перегрузки участвуют следующие сигнатуры функций:
A operator+(A) | ||
T* operator+(T*) | ||
A operator-(A) |
#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';
}Возможный вывод:
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
Арифметические операторы
Выражения операторов сложения имеют вид
lhs + rhs | (1) | |
lhs - rhs | (2) |
Бинарные + и - операторы имеют более высокий приоритет, чем все другие бинарные арифметические операторы, за исключением *, / и %. Эти операторы ассоциируются слева направо:
a + b * c; // equivalent to a + (b * c), NOT (a + b) * c d / e - f; // equivalent to (d / e) - f, NOT d / (e - f) g + h >> i; // equivalent to (g + h) >> i, NOT g + (h >> i) j - k + l - m; // equivalent to ((j - k) + l) - m
Встроенные операторы сложения
Для встроенных бинарных операторов сложения и вычитания оба lhs и rhs должны быть prvalue, и должно быть выполнено одно из следующих условий:
- Оба операнда имеют арифметический или неименованный перечислимый тип. В этом случае, на оба операнда выполняются обычные арифметические преобразования.
- Ровно один операнд имеет целочисленный или неименованный перечислимый тип. В этом случае, к этому операнду применяется целочисленное продвижение.
В оставшейся части этого раздела под «операндом(ами)», lhs и rhs подразумеваются преобразованные или продвинутые операнд(ы).
1) Для встроенного сложения должно быть выполнено одно из следующих условий:- Оба операнда имеют арифметический тип. В этом случае, результат — сумма операндов.
- Один операнд является указателем на полностью определённый тип объекта, а другой операнд имеет целочисленный тип. В этом случае, целочисленное значение добавляется к указателю (см. арифметику указателей).
- Оба операнда имеют арифметический тип. В этом случае, результат — разность, полученная в результате вычитания rhs из lhs.
- lhs является указателем на полностью определённый тип объекта, а rhs имеет целочисленный тип. В этом случае, целочисленное значение вычитается из указателя (см. арифметику указателей).
- Оба операнда являются указателями на cv-квалифицированные или cv-неквалифицированные версии одного и того же полностью определённого типа объекта. В этом случае rhs вычитается из lhs (см. арифметику указателей).
Если оба операнда имеют тип с плавающей точкой, и тип поддерживает арифметику IEEE с плавающей точкой (см. std::numeric_limits::is_iec559):
- Если один из операндов — NaN, результат — NaN.
- Бесконечность минус бесконечность — NaN, и
FE_INVALIDподнимается. - Бесконечность плюс отрицательная бесконечность — NaN, и
FE_INVALIDподнимается.
Арифметика указателей
Когда выражение J целочисленного типа добавляется к или вычитается из выражения P указательного типа, результат имеет тип P.
- Если
Pпринимает значение нулевого указателя иJпринимает значение0, результат — значение нулевого указателя. - В противном случае, если
Pуказывает наi-й элемент объекта массиваxсnэлементами, учитывая значениеJкакj,Pдобавляется или вычитается следующим образом: - Выражения
P + JиJ + P - указывают на
i+j-й элементx, еслиi + jнаходится в[0,n), и - являются указателями за пределами последнего элемента
xеслиi + jравноn. - Выражение
P - J - указывает на
i-j-й элементx, еслиi - jнаходится в[0,n), и - является указателем за пределами последнего элемента
xеслиi - jравноn. - Другие
jзначения приводят к неопределённому поведению. - В противном случае, если
Pуказывает на завершённый объект, подобъект базового класса или подобъект членаy, учитывая значениеJкакj,Pдобавляется или вычитается следующим образом: - Выражения
P + JиJ + P - указывают на
yеслиjравно0, и - являются указателями за пределами
yеслиjравно1. - Выражение
P - J - указывает на
yеслиjравно0, и - является указателем за пределами
yеслиjравно-1. - Другие
jзначения приводят к неопределённому поведению. - В противном случае поведение неопределённо.
Когда два указательных выражения P и Q вычитаются, тип результата — std::ptrdiff_t.
- Если
PиQоба принимают значения нулевого указателя, результат —0. - В противном случае, если
PиQуказывают соответственно наi-й иj-й элементы массива одного и того же объекта массиваx, выражениеP - Qимеет значениеi − j. - Если
i − jне может быть представленоstd::ptrdiff_t, поведение неопределённо. - В противном случае, если
PиQуказывают на один и тот же завершённый объект, подобъект базового класса или подобъект члена, результат —0. - В противном случае поведение неопределённо.
Эти операторы арифметики указателей позволяют указателям удовлетворять требованиям LegacyRandomAccessIterator.
Для сложения и вычитания, если P или Q имеют тип «указатель на (возможно, с квалификаторами cv) T», где T и тип элемента массива не являются аналогичными, поведение не определено:
int arr[5] = {1, 2, 3, 4, 5};
unsigned int *p = reinterpret_cast<unsigned int*>(arr + 1);
unsigned int k = *p; // OK, the value of `k` is 2
unsigned int *q = p + 1; // undefined behavior: `p` points to int, not unsigned intПерегрузки
При разрешении перегрузки по пользовательским операторам, для каждой пары типов продвигаемых арифметических типов L и R и для каждого типа объекта T, следующие подписи функций участвуют в разрешении перегрузки:
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*) |
где LR является результатом обычных арифметических преобразований над L и R.
#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';
}Вывод:
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
Операторы умножения
Выражения с операторами умножения имеют вид
lhs * rhs | (1) | |
lhs / rhs | (2) | |
lhs % rhs | (3) |
Операторы умножения имеют более высокий приоритет, чем все остальные бинарные арифметические операторы. Эти операторы ассоциативны слева направо:
a + b * c; // equivalent to a + (b * c), NOT (a + b) * c d / e - f; // equivalent to (d / e) - f, NOT d / (e - f) g % h >> i; // equivalent to (g % h) >> i, NOT g % (h >> i) j * k / l % m; // equivalent to ((j * k) / l) % m
Встроенные операторы умножения
Для встроенных операторов умножения и деления оба операнда должны иметь арифметический или тип перечисления без области видимости. Для встроенного оператора остатка от деления оба операнда должны иметь целочисленный тип или тип перечисления без области видимости. Обычные арифметические преобразования выполняются над обоими операндами.
В остальной части описания в этом разделе «операнд(ы)», lhs и rhs относятся к преобразованному(ым) операнду(ам).
std::numeric_limits::is_iec559): - Умножение NaN на любое число даёт NaN.
- Умножение бесконечности на ноль даёт NaN и поднимает
FE_INVALID.
std::numeric_limits::is_iec559) : - Если один операнд — NaN, результат — NaN.
- Деление ненулевого числа на ±0.0 даёт правильно знаковое бесконечность и поднимает
FE_DIVBYZERO. - Деление 0.0 на 0.0 даёт NaN и поднимает
FE_INVALID.
a / b представимо в типе результата, (a / b) * b + a % b == a. a / b не представимо в типе результата, поведение как a / b, так и a % b не определено (что означает, что INT_MIN % -1 не определено в системах со дополнительным кодом). Примечание: До тех пор, пока не был решён вопрос CWG 614 (N2757), если один или оба операнда бинарного оператора % были отрицательными, знак остатка был определён реализацией, так как он зависит от направления округления целочисленного деления. Функция std::div обеспечивала в этом случае хорошо определённое поведение.
Примечание: для остатка с плавающей точкой см. std::remainder и std::fmod.
Перегрузки
При разрешении перегрузки относительно пользовательских операторов, для каждой пары типов продвинутых арифметических LA и RA и для каждой пары типов продвинутых целых LI и RI следующие сигнатуры функций участвуют в разрешении перегрузки:
LRA operator*(LA, RA) | ||
LRA operator/(LA, RA) | ||
LRI operator%(LI, RI) |
где LRx — результат обычных арифметических преобразований над Lx и Rx.
#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';
}Вывод:
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
Битовые логические операторы
Выражения битовых логических операторов имеют вид
lhs ~ rhs | (1) | |
lhs & rhs | (2) | |
lhs | rhs | (3) | |
lhs ^ rhs | (4) |
Оператор битового НЕ имеет более высокий приоритет, чем все бинарные арифметические операторы. Он ассоциируется справа налево:
~a - b; // equivalent to (~a) - b, NOT ~(a - b) ~c * d; // equivalent to (~c) * d, NOT ~(c * d) ~-e; // equivalent to ~(-e)
В грамматике возникает неоднозначность, когда ~ следует за именем типа или decltype спецификатором(с C++11): это может быть либо оператор~ , либо начало деструктора. Неоднозначность разрешается путём обработки ~ как оператора~. ~ может начинать идентификатор деструктора только в местах, где формирование оператора~ синтаксически недействительно.
Все остальные битовые логические операторы имеют более низкий приоритет, чем все остальные бинарные арифметические операторы. Битовое И имеет более высокий приоритет, чем битовое ИСКЛЮЧАЮЩЕЕ ИЛИ, которое имеет более высокий приоритет, чем битовое ИЛИ. Они ассоциируются слева направо:
a & b * c; // equivalent to a & (b * c), NOT (a & b) * c d / e ^ f; // equivalent to (d ^ e) - f, NOT d ^ (e - f) g << h | i; // equivalent to (g << h) | i, NOT g << (h | i) j & k & l; // equivalent to (j & k) & l m | n ^ o // equivalent to m | (n ^ o)
Встроенные битовые логические операторы
Для встроенного оператора битового НЕ, rhs должен быть выражением-значением целого типа или типа несвязанного перечисления, и выполняется целочисленное продвижение для rhs. Для других встроенных битовых логических операторов оба операнда должны иметь целочисленный тип или тип несвязанного перечисления, и выполняются обычные арифметические преобразования для обоих операндов.
В остальном описании в этом разделе, «операнды», lhs и rhs относятся к преобразованным или продвинутым операндам.
1) Учитывая операнд какx и результат встроенной операции битового НЕ как r. Для каждого коэффициента x_i двоичного представления x, соответствующий коэффициент r_i двоичного представления r равен 1, если x_i равно 0, и 0 в противном случае. - Другими словами, результат — это дополнение до единицы операнда (где операнд и результат рассматриваются как беззнаковые).
r — это тип операнда x. x и y соответственно и результат встроенных бинарных битовых логических операций как r. Для каждой пары коэффициентов x_i и y_i двоичных представлений x и y соответственно, соответствующий коэффициент r_i двоичного представления r равен1 если оба x_i и y_i равны 1, и 0 в противном случае.1 если хотя бы один из x_i и y_i равен 1, и 0 в противном случае.1 если либо (но не оба) из x_i и y_i равны 1, и 0 в противном случае. r — это тип операндов x и y. Перегрузки
В разрешении перегрузки относительно пользовательских операторов, для каждой пары типов продвинутых целых L и R следующие сигнатуры функций участвуют в разрешении перегрузки:
R operator~(R) | ||
LR operator&(L, R) | ||
LR operator^(L, R) | ||
LR operator|(L, R) |
где LR — результат обычных арифметических преобразований над L и R.
#include <bitset>
#include <cstdint>
#include <iomanip>
#include <iostream>
int main()
{
std::uint16_t mask = 0x00f0;
std::uint32_t x0 = 0x12345678;
std::uint32_t x1 = x0 | mask;
std::uint32_t x2 = x0 & ~mask;
std::uint32_t x3 = x0 & mask;
std::uint32_t x4 = x0 ^ mask;
std::uint32_t x5 = ~x0;
using bin16 = std::bitset<16>;
using bin32 = std::bitset<32>;
std::cout << std::hex << std::showbase
<< "Mask: " << mask << std::setw(49) << bin16(mask) << "\n"
"Value: " << x0 << std::setw(42) << bin32(x0) << "\n"
"Setting bits: " << x1 << std::setw(35) << bin32(x1) << "\n"
"Clearing bits: " << x2 << std::setw(34) << bin32(x2) << "\n"
"Selecting bits: " << x3 << std::setw(39) << bin32(x3) << "\n"
"XOR-ing bits: " << x4 << std::setw(35) << bin32(x4) << "\n"
"Inverting bits: " << x5 << std::setw(33) << bin32(x5) << '\n';
}Вывод:
Mask: 0xf0 0000000011110000 Value: 0x12345678 00010010001101000101011001111000 Setting bits: 0x123456f8 00010010001101000101011011111000 Clearing bits: 0x12345608 00010010001101000101011000001000 Selecting bits: 0x70 00000000000000000000000001110000 XOR-ing bits: 0x12345688 00010010001101000101011010001000 Inverting bits: 0xedcba987 11101101110010111010100110000111
Операторы битового сдвига
Выражения операторов битового сдвига имеют вид
lhs << rhs | (1) | |
lhs >> rhs | (2) |
Операторы битового сдвига имеют более высокий приоритет, чем битовые логические операторы, но имеют более низкий приоритет, чем аддитивные и мультипликативные операторы. Эти операторы ассоциируются слева направо:
a >> b * c; // equivalent to a >> (b * c), NOT (a >> b) * c d << e & f; // equivalent to (d << e) & f, NOT d << (e & f) g << h >> i; // equivalent to (g << h) >> i, NOT g << (h >> i)
Встроенные операторы битового сдвига
Для встроенных операторов битового сдвига оба операнда должны быть выражениями-значениями целочисленного типа или типа несвязанного перечисления. Выполняются целочисленные продвижения для обоих операндов.
В оставшемся описании в этом разделе «операнды», a, b, lhs и rhs относятся к преобразованным или продвинутым операндам.
| Для беззнакового Для знакового и неотрицательного Для отрицательного Для беззнакового Для отрицательного | (до C++20) |
| Значение Значение | (с C++20) |
Тип результата — тип lhs. Если значение rhs отрицательное или не меньше количества битов в lhs, поведение не определено.
Перегрузки
При разрешении перегрузки по отношению к пользовательским операторам, для каждой пары типов целых типов L и R, следующие сигнатуры функций участвуют в разрешении перегрузки:
L operator<<(L, R) | ||
L operator>>(L, R) |
#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';
}Вывод:
0x123 << 1 = 0x246 0x123 << 63 = 0x8000000000000000 0x10 << 10 = 0x4000 -1000 >> 1 = -500
Стандартная библиотека
Арифметические операторы перегружены для многих типов стандартной библиотеки.
Унарные арифметические операторы
| реализует унарные + и - (публичный член-функция std::chrono::duration<Rep,Period>) |
|
| применяет унарные операторы к комплексным числам (функция-шаблон) |
|
| применяет унарный арифметический оператор к каждому элементу valarray (публичный член-функция std::valarray<T>) |
Арифметические операторы сложения
|
(C++11) | выполняет операции сложения и вычитания, включающие временную точку (функция-шаблон) |
|
(C++11) | реализует арифметические операции с продолжительностью в качестве аргументов (функция-шаблон) |
|
(C++20) | добавляет или вычитает year_month_day и некоторое количество лет или месяцев (функция) |
| конкатенирует две строки или строку и char (функция-шаблон) |
|
| перемещает или уменьшает итератор (публичный член-функция std::reverse_iterator<Iter>) |
|
| перемещает или уменьшает итератор (публичный член-функция std::move_iterator<Iter>) |
|
| выполняет арифметические операции с комплексными числами над двумя комплексными значениями или комплексным и скалярным (функция-шаблон) |
|
| применяет бинарные операторы к каждому элементу двух valarray или valarray и значения (функция-шаблон) |
Мультипликативные операторы
|
(C++11) | реализует арифметические операции с продолжительностью в качестве аргументов (функция-шаблон) |
| выполняет арифметические операции с комплексными числами над двумя комплексными значениями или комплексным и скалярным (функция-шаблон) |
|
| применяет бинарные операторы к каждому элементу двух valarray или valarray и значения (функция-шаблон) |
Побитовые логические операторы
| выполняет бинарные AND, OR, XOR и NOT (публичный член-функция std::bitset<N>) |
|
| выполняет бинарные логические операции над bitset (функция-шаблон) |
|
| применяет унарный арифметический оператор к каждому элементу valarray (публичный член-функция std::valarray<T>) |
|
| применяет бинарные операторы к каждому элементу двух valarray или valarray и значения (функция-шаблон) |
Побитовые операторы сдвига
| применяет бинарные операторы к каждому элементу двух valarray или valarray и значению (шаблон функции) |
|
| выполняет сдвиги влево и вправо (общедоступный член-функция std::bitset<N>) |
Операторы вставки/извлечения из потока
В стандартной библиотеке операторы побитового сдвига часто перегружаются для ввода-вывода потоков (std::ios_base& или одного из классов, производных от него) как левого операнда и типа возвращаемого значения. Такие операторы известны как операторы вставки в поток и операторы извлечения из потока:
| извлекает отформатированные данные (общедоступный член-функция std::basic_istream<CharT,Traits>) |
|
| извлекает символы и массивы символов (шаблон функции) |
|
| вставляет отформатированные данные (общедоступный член-функция std::basic_ostream<CharT,Traits>) |
|
| вставляет символьные данные или вставляет в поток правого значения (шаблон функции) |
|
| сериализует и десериализует комплексное число (шаблон функции) |
|
| выполняет ввод и вывод bitset в поток (шаблон функции) |
|
| выполняет ввод и вывод строк в поток (шаблон функции) |
|
| (C++11) | выполняет ввод и вывод псевдослучайного генератора чисел в поток (шаблон функции) |
| (C++11) | выполняет ввод и вывод распределения псевдослучайных чисел в поток (шаблон функции) |
Отчеты об ошибках
Следующие отчеты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применён к | Поведение при публикации | Корректное поведение |
|---|---|---|---|
| CWG 614 | C++98 | алгебраическое частное целочисленного деления округлялось в реализации, заданной направление | алгебраическое частное целочисленного деления усекается к нулю (дробная часть отбрасывается) |
| CWG 1450 | C++98 | результат a / b был неопределенным,если он не представим в типе результата | поведение a / b иa % b в этом случае не определено |
| CWG 1457 | C++98 | поведение сдвига самого левого 1 битаположительного знакового значения в бит знака было неопределенным | сделано определенным |
| CWG 1504 | C++98 | указатель на подобъект базового класса элемента массива мог использоваться в арифметике указателей | поведение в этом случае не определено |
| CWG 1515 | C++98 | только целые беззнаковые, которые объявлены unsigned должны подчиняться законам арифметики по модулю 2n | применимо ко всем беззнаковым целым числам |
| CWG 1642 | C++98 | арифметические операторы позволяют своим операндам быть lvalue | некоторые операнды должны быть rvalue |
| CWG 1865 | C++98 | разрешение CWG issue 1504 сделало поведение арифметики указателей, включающей указатели на элементы массива неопределенным, если тип указываемого объекта и тип элемента массива имеют различные cv-квалификаторы на уровнях, не являющихся верхними | сделано определенным |
| CWG 1971 | C++98 | не было ясно, применяется ли правило разрешения неопределенности ~ к таким случаям, как ~X(0) | правило применяется к таким случаям |
| CWG 2419 | C++98 | указатель на объект, не являющийся массивом, рассматривался как указатель на первый элемент массива размером 1 в арифметике указателей, если указатель получен посредством & | применимо ко всем указателям на объекты, не являющиеся массивами |
| CWG 2626 | C++98 | результат встроенного operator~ был просто'дополнительным кодом' без надлежащего определения | результат сформулирован в терминах представления в системе счисления по основанию 2 |
| CWG 2724 | C++20 | направление округления арифметического сдвига вправо было неясным | сделано ясным |
См. также
END_OF_DOCUMENT_MARKER| Общие операторы | ||||||
|---|---|---|---|---|---|---|
| присваивание |
инкремент декремент | арифметические | логические | сравнения |
доступ к членам | другие |
|
|
|
|
|
|
| вызов функции |
a(...) |
||||||
| запятая | ||||||
a, b |
||||||
| условный | ||||||
a ? b : c |
||||||
| Специальные операторы | ||||||
|
|
||||||
| C документация для Арифметических операторов |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/operator_arithmetic