算術演算子
特定の算術演算の結果を返します。
| 演算子名 | 構文 | プロトタイプの例 (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); | |
| ビット単位NOT | ~a | T T::operator~() const; | T operator~(const T& a); | |
| ビット単位AND | a & b | T T::operator&(const T2& b) const; | T operator&(const T& a, const T2& b); | |
| ビット単位OR | a | b | T T::operator|(const T2& b) const; | T operator|(const T& a, const T2& b); | |
| ビット単位XOR | 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-to-rvalue変換が適用される場合はその後)整数昇格が行われます。オペランドが配列型または関数型の場合、配列からポインタへの変換と関数からポインタへの変換が適用されます。
二項演算子(シフトを除く)の場合、昇格されたオペランドの型が異なる場合、通常の算術変換が適用されます。
[編集] オーバーフロー
符号なし整数の算術演算は常に2nを法として実行されます。ここで n はその特定の整数のビット数です。例えば、unsigned intの場合、UINT_MAXに1を加えると0になり、0から1を引くとUINT_MAXになります。
符号付き整数の算術演算がオーバーフローした場合(結果が結果の型に収まらない場合)、動作は未定義です。このような演算の考えられる現れ方としては、
- 表現規則に従ってラップアラウンドする(通常は2の補数)、
- トラップする — 一部のプラットフォームまたはコンパイラオプション(例: GCCおよびClangの
-ftrapv)により、 - 最小値または最大値に飽和する(多くのDSPの場合)、
- コンパイラによって完全に最適化されてしまう。
[編集] 浮動小数点環境
#pragma STDC FENV_ACCESS がサポートされており ON に設定されている場合、すべての浮動小数点算術演算子は現在の浮動小数点丸め方向に従い、静的初期化子の一部でない限り(この場合、浮動小数点例外は発生せず、丸めモードは最近接丸めになります)、math_errhandlingで指定された浮動小数点算術エラーを報告します。
[編集] 浮動小数点縮約
#pragma STDC FP_CONTRACT がサポートされ、OFF に設定されていない限り、すべての浮動小数点演算は、中間結果が無限の範囲と精度を持つかのように実行される可能性があります。つまり、丸め誤差や浮動小数点例外を省略する最適化が許可されます。例えば、C++では(x * y) + zを単一の積和演算CPU命令で実装したり、a = x * x * x * x;をtmp = x * x; a = tmp * tmpとして最適化したりすることができます。
縮約とは無関係に、浮動小数点演算の中間結果は、その型によって示されるものとは異なる範囲と精度を持つ可能性があります。詳細はFLT_EVAL_METHODを参照してください。
形式的には、C++標準は浮動小数点演算の精度に関して何の保証もしていません。
[編集] 単項算術演算子
単項算術演算子の式は以下の形式をとります。
+ expression |
(1) | ||||||||
- expression |
(2) | ||||||||
単項+および-演算子は、すべての二項算術演算子よりも高い優先順位を持つため、expressionはトップレベルの二項算術演算子を含むことはできません。これらの演算子は右から左へ結合します。
+a - b; // equivalent to (+a) - b, NOT +(a - b) -c + d; // equivalent to (-c) + d, NOT -(c + d) +-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 already
[編集] 組み込み単項算術演算子
- 言い換えれば、結果はオペランドの2の補数です(オペランドと結果は符号なしとみなされます)。
[編集] オーバーロード
ユーザー定義演算子のオーバーロード解決において、すべての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であり、以下のいずれかの条件を満たす必要があります。
- 両方のオペランドが算術型またはスコープなし列挙型である。この場合、両方のオペランドに対して通常の算術変換が実行されます。
- ちょうど1つのオペランドが整数型またはスコープなし列挙型である。この場合、そのオペランドに対して整数昇格が適用されます。
このセクションの残りの説明では、「オペランド」、「lhs」、「rhs」は変換または昇格されたオペランドを指します。
- 両方のオペランドが算術型である。この場合、結果はオペランドの合計です。
- 一方のオペランドが完全に定義されたオブジェクト型へのポインタであり、もう一方のオペランドが整数型である。この場合、整数値がポインタに加算されます(ポインタ演算を参照)。
両方のオペランドが浮動小数点型であり、その型がIEEE浮動小数点演算をサポートしている場合(std::numeric_limits::is_iec559を参照)
- 一方のオペランドがNaNの場合、結果はNaNです。
- 無限大から無限大を引くとNaNになり、FE_INVALIDが設定されます。
- 無限大に負の無限大を加えるとNaNになり、FE_INVALIDが設定されます。
[編集] ポインタ演算
整数型を持つ式Jがポインタ型を持つ式Pに加算または減算されると、結果はPの型を持ちます。
- もしPがヌルポインタ値に評価され、Jが0に評価される場合、結果はヌルポインタ値になります。
- それ以外の場合、Pがn個の要素を持つ配列オブジェクトxの
i番目の要素を指し、Jの値がjである場合、Pは次のように加算または減算されます。
- 式P + JとJ + Pは、
- i + jが
[0,n)の範囲内にある場合、xのi+j番目の要素を指し、 - i + jがnである場合、xの最後の要素の終端を超えるポインタとなります。
- i + jが
- 式P - Jは、
- i - jが
[0,n)の範囲内にある場合、xのi-j番目の要素を指し、 - i - jがnである場合、xの最後の要素の終端を超えるポインタとなります。
- i - jが
- その他のjの値は未定義動作となります。
- それ以外の場合、Pが完全なオブジェクト、基底クラスのサブオブジェクト、またはメンバサブオブジェクトyを指し、Jの値がjである場合、Pは次のように加算または減算されます。
- 式P + JとJ + Pは、
- jが0である場合、yを指し、
- jが1である場合、yの終端を超えるポインタとなります。
- 式P - Jは、
- jが0である場合、yを指し、
- jが-1である場合、yの終端を超えるポインタとなります。
- その他のjの値は未定義動作となります。
- それ以外の場合、Pがオブジェクトzの終端を超えるポインタであり、Jの値がjである場合、
- もしzがn個の要素を持つ配列オブジェクトである場合、Pは次のように加算または減算されます。
- 式P + JとJ + Pは、
- n + jが
[0,n)の範囲内にある場合、zのn+j番目の要素を指し、 - jが0である場合、zの最後の要素の終端を超えるポインタとなります。
- n + jが
- 式P - Jは、
- n - jが
[0,n)の範囲内にある場合、zのn-j番目の要素を指し、 - jが0である場合、zの最後の要素の終端を超えるポインタとなります。
- n - jが
- その他のjの値は未定義動作となります。
- それ以外の場合、Pは次のように加算または減算されます。
- 式P + JとJ + Pは、
- jが-1である場合、zを指し、
- jが0である場合、zの終端を超えるポインタとなります。
- 式P - Jは、
- jが1である場合、zを指し、
- jが0である場合、zの終端を超えるポインタとなります。
- その他のjの値は未定義動作となります。
- それ以外の場合、動作は未定義です。
2つのポインタ式PとQが減算される場合、結果の型はstd::ptrdiff_tです。
- もしPとQの両方がヌルポインタ値に評価される場合、結果は0です。
- それ以外の場合、PとQがそれぞれ同じ配列オブジェクトxの
i番目とj番目の配列要素を指す場合、式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」は変換されたオペランドを指します。
- NaNに任意の数を乗算するとNaNになります。
- 無限大にゼロを乗算するとNaNになり、FE_INVALIDが設定されます。
- 一方のオペランドがNaNの場合、結果はNaNです。
- ゼロでない数を±0.0で割ると、正しい符号の無限大になり、FE_DIVBYZEROが設定されます。
- 0.0を0.0で割るとNaNになり、FE_INVALIDが設定されます。
注: CWG issue 614が解決されるまで(N2757)、二項演算子%のオペランドが1つ以上負の場合、剰余の符号は整数除算の丸め方向によって実装定義でした。この場合、関数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
[編集] ビット単位論理演算子
ビット単位論理演算子の式は以下の形式をとります。
~ rhs |
(1) | ||||||||
lhs & rhs |
(2) | ||||||||
lhs | rhs |
(3) | ||||||||
lhs ^ rhs |
(4) | ||||||||
ビット単位NOT演算子は、すべての二項算術演算子よりも高い優先順位を持ちます。右から左へ結合します。
~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以降)が続く場合、文法上の曖昧さがあります。これは、operator~であるか、デストラクタ識別子の開始であるかのいずれかです。この曖昧さは、~をoperator~として扱うことで解決されます。~がデストラクタ識別子を開始できるのは、operator~を形成することが構文的に無効な場所に限られます。
他のすべてのビット単位論理演算子は、他のすべての二項算術演算子よりも低い優先順位を持ちます。ビット単位ANDはビット単位XORよりも優先順位が高く、ビット単位XORはビット単位ORよりも優先順位が高いです。これらは左から右へ結合します。
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)
[編集] 組み込みビット単位論理演算子
組み込みビット単位NOT演算子の場合、rhsは整数型またはスコープなし列挙型のprvalueでなければならず、rhsに対して整数昇格が実行されます。他の組み込みビット単位論理演算子の場合、両方のオペランドは整数型またはスコープなし列挙型でなければならず、両方のオペランドに対して通常の算術変換が実行されます。
このセクションの残りの説明では、「オペランド」、「lhs」、「rhs」は変換または昇格されたオペランドを指します。
- 言い換えれば、結果はオペランドの1の補数です(オペランドと結果は符号なしとみなされます)。
[編集] オーバーロード
ユーザー定義演算子のオーバーロード解決において、昇格された整数型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)
[編集] 組み込みビット単位シフト演算子
組み込みビット単位シフト演算子の場合、両方のオペランドは整数型またはスコープなし列挙型のprvalueでなければなりません。両方のオペランドに対して整数昇格が実行されます。
このセクションの残りの説明では、「オペランド」、a、b、lhs、rhsは変換または昇格されたオペランドを指します。
もしrhsの値が負であるか、lhsのビット数以上である場合、動作は未定義です。
|
符号なしaの場合、a << bの値はa * 2bを戻り値の型のビット数Nを法として減算した値です(つまり、ビット単位左シフトが実行され、目的の型からシフトアウトされたビットは破棄されます)。 符号付きかつ非負のaの場合、もしa * 2bが戻り値の型の符号なし版で表現可能であれば、その値は符号付きに変換され、a << bの値となります(これにより、INT_MINを1 << 31として作成することが合法になります)。それ以外の場合、動作は未定義です。 負のaの場合、a << bの動作は未定義です。 符号なしaおよび符号付きかつ非負のaの場合、a >> bの値はa/2bの整数部分です。 負のaの場合、a >> bの値は実装定義です(ほとんどの実装では、これは算術右シフトを実行し、結果は負のままになります)。 |
(C++20まで) |
|
a << bの値は、a * 2bを戻り値の型のビット数Nを法として合同な一意の値です(つまり、ビット単位左シフトが実行され、目的の型からシフトアウトされたビットは破棄されます)。 a >> bの値はa/2bであり、負の無限大に向かって丸められます(言い換えれば、符号付きaに対する右シフトは算術右シフトです)。 |
(C++20以降) |
結果の型は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>のpublicメンバ関数) | |
| 複素数に単項演算子を適用する (関数テンプレート) | |
| valarrayの各要素に単項算術演算子を適用する ( std::valarray<T>のpublicメンバ関数) |
[編集] 加算演算子
| (C++11) |
タイムポイントを含む加算および減算演算を実行 (関数テンプレート) |
| 期間を引数とする算術演算を実装 (関数テンプレート) | |
| (C++20) |
year_month_dayと年数または月数を加算または減算(関数) |
| 2つの文字列、文字列と char、または文字列と string_view を連結する (function template) | |
| イテレータを進めるまたは減らす ( std::reverse_iterator<Iter>のpublicメンバ関数)
| |
| イテレータを進めるまたは減らす ( std::move_iterator<Iter>のpublicメンバ関数)
| |
| 2つの複素数値、または複素数とスカラ値の複素数演算を実行する (関数テンプレート) | |
| 2つのvalarray、またはvalarrayと値の各要素に二項演算子を適用する (function template) |
[編集] 乗算演算子
| 期間を引数とする算術演算を実装 (関数テンプレート) | |
| 2つの複素数値、または複素数とスカラ値の複素数演算を実行する (関数テンプレート) | |
| 2つのvalarray、またはvalarrayと値の各要素に二項演算子を適用する (function template) |
[編集] ビット単位論理演算子
| ビット単位のAND、OR、XOR、NOTを実行する ( std::bitset<N>のpublicメンバ関数) | |
| ビットセットに対するビット単位の論理演算を実行する (function template) | |
| valarrayの各要素に単項算術演算子を適用する ( std::valarray<T>のpublicメンバ関数)
| |
| 2つのvalarray、またはvalarrayと値の各要素に二項演算子を適用する (関数テンプレート) |
[編集] ビット単位シフト演算子
| 2つのvalarray、またはvalarrayと値の各要素に二項演算子を適用する (関数テンプレート) | |
| ビット単位の左シフトと右シフトを実行する ( std::bitset<N>のpublicメンバ関数)
|
[編集] ストリーム挿入/抽出演算子
標準ライブラリ全体で、ビット単位シフト演算子はI/Oストリーム(std::ios_base&またはそこから派生したクラスのいずれか)を左オペランドと戻り値の型の両方として持つように一般的にオーバーロードされています。このような演算子はストリーム挿入およびストリーム抽出演算子として知られています。
| 書式付きデータを抽出する ( std::basic_istream<CharT,Traits>のpublicメンバ関数) | |
| 文字と文字配列を抽出する (function template) | |
| 書式付きデータを挿入する ( std::basic_ostream<CharT,Traits>のpublicメンバ関数) | |
| 文字データを挿入する、または右辺値ストリームに挿入する (function template) | |
| 複素数をシリアライズ・デシリアライズする (関数テンプレート) | |
| ビットセットのストリーム入出力を実行する (function template) | |
| 文字列に対するストリーム入出力を実行する (function template) | |
| (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ビットを符号ビットにシフトする動作は未定義であった正の符号付き値の最左の 1ビットを |
符号ビットにシフトする動作は定義された |
| CWG 1504 | C++98 | 配列要素の基底クラスサブオブジェクトへのポインタは、ポインタ演算で使用できなかった 配列要素の基底クラスサブオブジェクトへのポインタも |
この場合の動作は 未定義となる |
| ポインタ演算で使用できるようになった | C++98 | CWG 1515 unsignedと宣言された符号なし整数のみが算術法則modulo 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の配列の最初の要素へのポインタとしてポインタ演算で扱われた 非配列オブジェクトへのポインタは、 &で取得された場合にのみ、サイズ1の配列の最初の要素への |
ポインタとしてポインタ演算で扱われた すべての非配列オブジェクトへのポインタに適用される |
| CWG 2626 | C++98 | 組み込みoperator~の結果は、「1の補数」としか定義されていなかった結果は、「1の補数」としか定義されていなかった |
結果は2進数表現の観点から表現される 結果は2進数表現の観点から表現される |
| CWG 2724 | C++20 | 算術右シフトの丸め方向が不明確であった | 明確化された |
| CWG 2853 | C++98 | オブジェクトの終端を超えるポインタは、整数との加算または減算ができなかった オブジェクトの終端を超えるポインタも |
できる |
[編集] 関連項目
| 共通の演算子 | ||||||
|---|---|---|---|---|---|---|
| 代入 | インクリメント デクリメント |
算術 | 論理 | 比較 | メンバ アクセス |
その他 |
|
a = b |
++a |
+a |
!a |
a == b |
a[...] |
関数呼び出し a(...) |
| コンマ a, b | ||||||
| conditional a ? b : c | ||||||
| 特殊な演算子 | ||||||
|
static_castは、ある型を関連する別の型に変換する | ||||||
| Cドキュメント - 算術演算子
|