一般論 | |||||||||
フロー制御 | |||||||||
条件式 LI 条件のあるもの |
|
||||
反復文(ループ) | ||||
範囲- LI
|
範囲- for (C++11) |
|||
Jump文 | ||||
|
|
|||
関数 | ||||
ラムダ関数宣言 | ||||
inline 指定子 |
||||
例外指定 (C++20迄) | ||||
指定子 noexcept 指定子(C++11) |
||||
例外 | ||||
名前空間 | ||||
タイプ | ||||
スペシファイア | ||||
const/ |
||||
保存期間指定子 | ||||
。 初期化 | ||||
式 | ||||
代替表現 | ||||
文字 | ||||
ブール値 – 論理値 整数 – 浮動小数点 | ||||
文字 – 文字列 – nullptr (C++11) |
||||
User-> (C++11)定義済み (C++11) | ||||
ユーティリティ | ||||
属性 (C++11) | ||||
タイプ | ||||
typedef 宣言 |
||||
型エイリアス宣言(C++11) | ||||
キャスト | ||||
暗黙の変換 – 。 明示的な変換 | ||||
static_cast – dynamic_cast |
||||
const_cast – 。 reinterpret_cast |
||||
メモリ割り当て | ||||
クラス | ||||
クラス・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 17特定関数プロパティ | ||||
仮想関数 override 指定子 (C++11) final 指定子 (C++11) |
指定子 |
|||
テンプレート | ||||
テンプレート指定 パラメータパック(C++11) |
||||
その他 | ||||
一般
値カテゴリ (lvalue.XXX)
評価順序(シーケンスポイント)
定数式
未評価式
一次式
ラムダ式(C++11)
リテール
整数リテラル
浮動小数 (σ)・・・・・?ポイント・リテラル
boolean リテラル
文字リテラル(エスケープシーケンスを含む)
string リテラル
null pointer リテール (C++11)
ユーザー定義リテラル (C++11)
オペレータ
Assignment operator.(割り当て演算子)です。 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||b
、a&&b
、!a
比較演算子。 a==b
, a!=b
, a<b
, a>b
, a<=b
, a>=b
, a<=>b
(C++20)
メンバーアクセス演算子(MA) a
, *a
, &a
, a->b
, a.b
, a->*b
, a.*b
その他の演算子。 a(...)
, a,b
, a?b:c
new-expression
delete-expression
throw-expression
alignof
sizeof
sizeof…(英語)。(C++11)
typeid
noexcept(C++11)
Fold expression(C++17)
Operators Alternative Representations
Precedence and associativity
Operator Overloading
デフォルトの比較(C++20)
変換
暗黙の変換
const_cast
static_cast
reinterpret_cast
dynamic_cast
明示的変換 (T)a
, T(a)
ユーザ定義変換
特定の算術演算の結果を返します。
演算子名 | 構文 | オーバーロード可能 | プロトタイプ例(クラスTの場合) | |||||
---|---|---|---|---|---|---|---|---|
クラス内部定義 | クラス外部定義 | |||||||
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:.T. | T operator+(const T &a, const T2 &b); | ||||
subtraction | a - b |
Yes | T T:.T, T:.T, | 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.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.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:.T, T: :Operate | Yes | T: :operator|(const T2 &b)operator^(const T2 &b) const; | T operator^(const T &a, const T2 &b); | ||
bitwise 左シフト | 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 operator>>(const T &a, const T2 &b)とする。 | |||||
注意事項
|
内容
- 1 解説
- 1.1 変換
- 1.1 変換の種類は?2 オーバーフロー
- 1.3 浮動小数点環境
- 1.4 浮動小数点縮約
- 1.5 単項演算子
- 1.6 加算演算子
- 1.7 乗算演算子
- 1.8 ビット単位の論理演算子
- 1.9 ビットシフト演算子
- 2 標準ライブラリ
- 2.1 単項演算子
- 2.2 加算演算子
- 2.3 乗算演算子
- 2.4 ビット論理演算子
- 2.5 ビットシフト演算子
- 2.1 単項演算子
- 2.1 加算演算子
- 3.5 加算演算子 3.2 加算加算演算子
3 乗算演算子
- 3 欠陥報告
- 4 参照
説明
すべての算術演算子は特定の算術演算の結果を計算しその結果を返します。 引数は変更されない。
変換
算術演算子に渡されるオペランドが整数型または非スコープ列挙型の場合、他の操作の前に(ただし、適用可能であれば、lvalueからrvalueへの変換後に)、オペランドは整数昇格を受ける。
二項演算子(シフトを除く)において、昇格したオペランドが異なる型を持つ場合、共通の型を生成する目的で通常の算術変換として知られる、暗黙の追加変換セットが適用されます(std::common_type型特性からもアクセス可能)。 積分昇格の前に、一方のオペランドが列挙型で、他方のオペランドが浮動小数点型または異なる列挙型である場合、この動作は非推奨となります。 (C++20 以降)
- オペランドのいずれかがスコープ付き列挙型の場合、変換は行われない。 他方のオペランドと戻り値の型が同じでなければなりません
- そうでなければ、どちらかのオペランドが long double の場合、他方のオペランドは long double に変換されます
- そうでなければ、他方のオペランドが double の場合は、double に変換されます
- 。 どちらかのオペランドがfloatの場合、もう一方のオペランドをfloatに変換
- それ以外の場合、オペランドは整数型(この時点でbool, char, char8_t, char16_t, char32_t, wchar_t, 非スコープの列挙が昇進していたので)、以下のように整数変換が行われて共通型を生成している。
- オペランドが両方とも符号付き、または両方とも符号なしの場合、変換順位の小さいオペランドは、整数の変換順位の大きいオペランドに変換されます
- その他の場合、符号なしオペランドの変換順位が符号付きオペランドの変換順位と同じか大きい場合は、符号付きオペランドが符号なしオペランドのタイプに変換されます。
- それ以外の場合、符号付きオペランドの型が符号なしオペランドのすべての値を表現できる場合、符号なしオペランドは符号付きオペランドの型に変換される
- それ以外の場合、両方のオペランドは符号なしオペランドの型と同等に変換される。
上記の変換ランクはbool、 signed char、 short、 int、 long、 long longの順で大きくなる。 任意の符号なし型のランクは、対応する符号付き型のランクに等しくなります。 charのランクは、signed charとunsigned charのランクに等しい。 char8_t、char16_t、char32_t、wchar_tのランクは、それらの基本型のランクに等しい。
オーバーフロー
符号なし整数演算は常にmodulo 2n
(nはその特定の整数のビット数)で行われます。 例えば、符号なし整数では、UINT_MAX に 1 を加えると 0 になり、0 から 1 を引くと UINT_MAX になります。
符号付き整数演算がオーバーフローした場合 (結果が結果の型に収まらない場合)、その動作は未定義です。このような演算で起こりうる現象としては、
- 表現の規則に従って折り返す (一般的には 2 の補数)、
- トラップ – あるプラットフォームやコンパイラオプションによって (e.s.)GCC や Clang の
-ftrapv
など)、 - 最小値または最大値まで飽和する(多くの DSP で)、
- コンパイラによって完全に最適化される、などです。
浮動小数点演算環境
#pragma STDC FENV_ACCESS がサポートされ、かつ ON
に設定されていれば、浮動小数点演算は利用可能です。 すべての浮動小数点演算子は現在の浮動小数点丸め方向に従い、静的イニシャライザーの一部でない限り (この場合、浮動小数点例外は発生せず、丸めモードは nearest になります)、 math_errhandling で指定された浮動小数点演算エラーを報告します
浮動小数点縮小
#pragma STDC FP_CONTRACT がサポートされていて OFF
に設定されていなければ、浮動小数点丸め方向は異なります。 つまり、丸め誤差や浮動小数点例外処理を省略する最適化が許可されます。 例えば、C++では、(x*y)+zを1つの融合型乗算加算CPU命令で実装したり、a = x*x*x; as tmp = x *x; a = tmp*tmpの最適化が可能です。
請負とは関係ありませんが、浮動小数点演算の中間結果は、その型によって示されるものとは異なる範囲と精度を持つことがあります。FLT_EVAL_METHOD
形式的に、C++ 標準は浮動小数点演算の精度について保証していません。
単項演算子
単項演算子の表現は
+ 式 |
の形式である。 (1) | ||||||||
- 式 |
(2) | ||||||||
内蔵の単項演算子プラスは、そのオペランドの値を返します。 オペランドが整数型またはスコープされていない列挙型を持ち、それが積分昇格によって変更される場合、例えば char から int への変換、オペランドが lvalue から rvalue、配列からポインタ、または関数からポインタへの変換を受ける場合のみ、ノーオープンとはなりません。 符号なしa
の場合、-a
の値は2b
-aとなり、b
は昇格後のビット数です。
ユーザ定義演算子に対する過負荷解消では、昇格した演算型A
ごと、型T
ごとに、次の関数署名が過負荷解消に参加します。
#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; 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: 4294967295size of array: 3size of pointer: 8
加算演算子
二項加算演算子の式は
lhs + rhs の形をしています。 |
(1) | ||||||||
lhs - rhs |
(2) | ||||||||
- 両方とも算術型またはスコープなしの列挙型であること。
- 一方は完全に定義されたオブジェクト型へのポインタ、他方は積分型または非スコープの列挙型を持っています。 この場合、結果の型はポインタの型を持つ。
- 両方とも算術型か非スコープ型列挙型を持っている。
- lhsは完全に定義されたオブジェクト型へのポインタ、rhsは積分型または非スコープ型列挙型を持つ。
- 両方とも,cv-qualifiersを無視した,同じ完全に定義されたオブジェクト型へのポインタです. この場合、結果の型は std::ptrdiff_t となります。
算術型または列挙型のオペランドに対して、二項演算子の結果は(通常の算術変換後の)オペランドの和であり、二項演算子の結果は(通常の算術変換後の)第一オペランドから第二オペランドを減算した結果ですが、型がIEEE浮動小数点演算( std::numeric_limits: を参照)をサポートしていれば、その例外はありません。is_iec559),
- 1 つのオペランドが NaN の場合、結果は NaN
- infinity マイナス infinity は NaN で FE_INVALID は raise
- infinity プラス負の infinity は NaN で FE_INVALID は raised
オペランドのどれかがポインタの場合、次の規則が適用されます。
- 配列でないオブジェクトへのポインタは、サイズ1の配列の最初の要素へのポインタとして扱われます。
- ポインタ
P
が配列のi
番目の要素を指す場合、P+n
,n+P
,P-n
式はそれぞれ同じ配列のi+n
番目、i+n
番目、i-n
番目の要素を指す同じ型のポインタである。 ポインタの加算結果は、1つ前の終了ポインタ (つまり、式P-1
が配列の最後の要素を指すようなポインタP
) であることもある。 - ポインタ
P
が配列のi
番目の要素を指し、ポインタQ
が同じ配列のj
番目の要素を指す場合、式P-Q
は値 i-j (std::ptrdiff_t に値が入る場合) となる。 両オペランドは同じ配列の要素(または1つ後ろの要素)を指していなければならず、そうでない場合の動作は未定義である。 - いずれの場合でも,指された型が配列要素の型と異なる場合,要素がそれ自体ポインタであれば,cvの修飾を無視して,あらゆるレベルで,ポインタ演算の動作は不定となる. 特に、派生オブジェクトの配列の要素を指しているポインタをベースにしたポインタ演算は未定義です。
- ポインタに値0を加算または減算した場合、結果はポインタであり、変更されることはありません。 2 つのポインタが同じオブジェクトを指しているか、両方とも同じ配列の終端を 1 つ過ぎているか、両方とも null ポインタである場合、減算の結果は (std::ptrdiff_t)0 に等しい。
これらのポインタ算術演算子によりポインタが LegacyRandomAccessIterator 要求を満たすことができます。
ユーザー定義演算子に対するオーバーロード解決では、昇格した演算型L
とR
のすべてのペアとオブジェクト型T
について、以下の関数署名がオーバーロード解決に参加します。
。ptrdiff_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 = {'a', 'b', 'c', 'd'}; char* p = &a; std::cout << "Pointer addition examples: " << *p << *(p + 2) << *(2 + p) << *(p - 1) << '\n'; char* p2 = &a; 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.12Pointer addition examples: bddaPointer difference: 3
乗算演算子
二項乗算演算子の式は
lhs * rhs |
(1) | ||||||||
lhs / rhs |
(2) | ||||||||
lhs % rhs |
(3) | ||||||||
3つの演算子すべてについて、通常の算術変換が両方のオペランドで行われ、結果の型が決定される。
二項演算子 * は、そのオペランドの乗算を実行します(通常の算術変換の後)、ただし、浮動小数点数の乗算については、例外です。
- NaN と任意の数の乗算は NaN
- 無限大とゼロの乗算は NaN を与え FE_INVALID が発生
The binary operator / decides first operand by second (after usual arithmetic conversions.).
積分オペランドの場合、それは代数的な商を生成します。
商は、実装で定義された方向に丸められます。 |
(C++11まで) |
商はゼロに向けて切り捨てられます(小数部は破棄されます)。 |
(C++11以降) |
第2オペランドが0の場合、動作は未定義ですが、浮動小数点演算が実行され、型がIEEE浮動小数点演算をサポートしていれば(std::numeric_limits::is_iec559 参照)、:
- もし一方のオペランドが NaN なら、結果は NaN
- 0 でない数を ±0 で割ったものとなります。0 で割ると正しく符号化された無限大となり FE_DIVBYZERO が発生
- 0.0 で割ると NaN となり FE_INVALID が発生
二項演算子 % は最初のオペランドを 2 番目で整数分割した余りになります(通常の演算変換後;オペランド型が整数型でなければならないことに注意します)。 商a/b
が結果型で表現可能な場合、(a/b)*b + a%b == aとなる。第2オペランドが0の場合、動作は未定義である。 商 a/b
が結果の型で表現できない場合、a/b
と a%b
の両方の動作は不定です(つまり、INT_MIN%-1 は 2 の補数系では不定)
注:C++11 まで、二項演算子 % の一方または両方のオペランドが負の場合、余りの符号は整数分割時の丸め方向によって決まるため実装定義されていました。 その場合、関数 std::div は明確に定義された動作を提供しました。
注意: 浮動小数点の余りについては、std::remainder および std::fmod を参照してください。
ユーザー定義演算子に対するオーバーロード解決において、昇格した算術型 LA
と RA
の各ペア、昇格した積分型 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 = -202 * (-10), where 2 is unsigned = 4294967276-10 / 2.12 = -4.71698-10 / 21 = 0-10 % 21 = -10
ビット演算子
ビット演算子の式は
~ rhs |
(1) | ||||||||
(2) | |||||||||
lhs | rhs |
(3) | ||||||||
lhs ^ rhs |
(4) | ||||||||
operator~の結果は、引数のビット単位のNOT(1つの補数)値です(昇格の後)。 operator&の結果は、オペランドのビットごとのAND値(通常の算術変換後)です。 operator|の結果は、オペランドのビットごとのOR値です(通常の算術変換後)。 operator^ の結果は、オペランドのビットごとの XOR 値です(通常の算術変換後)
ユーザー定義演算子に対する過負荷解消では、昇格積分型のすべてのペア L
と R
に対して、次の関数署名が過負荷解消に関与しています。
ここで、LR
は、通常の L
と R
#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 | mask) << '\n' << "Clearing bits: " << (a & ~mask) << '\n' << "Selecting bits: " << (a & mask) << '\n';}
出力する。
Value: 0x12345678 mask: 0xf0Setting bits: 0x123456f8Clearing bits: 0x12345608Selecting bits: 0x70
ビットシフト演算子
ビットシフト演算子の式は
lhs << rhs |
(1) | ||||||||
lhs >> rhs |
(2) | ||||||||
戻り値の型は、積分昇格後の左オペランドの型になります。
符号なし 符号付きで非負の 負 符号なし 負 |
(C++20まで) |
の値は a * 2b |
(C++20以降) |
いずれの場合も、右オペランドの値が負または昇格左オペランドのビット数と同じか大きい場合は挙動は不定である。
ユーザー定義演算子に対する過負荷解消では、昇格した積分型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 = 0x2460x123 << 63 = 0x80000000000000000x10 << 10 = 0x4000-1000 >> 1 = -500
標準ライブラリ
算術演算子は多くの標準ライブラリ型に対してオーバーロードされています。
単項演算子
(
std::chrono::duration<Rep,Period>
のパブリックメンバ関数)
(関数テンプレート)
(
std::valarray<T>
のパブリックメンバ関数) について 加算演算子
(関数テンプレート)
(関数テンプレート)
year_month_day
とある値を加算・減算する。 年数または月数 (public member function of
std::chrono::year_month_day
)
(function template)
(public member function of
std::reverse_iterator<Iter>
)
(public member function of
std::move_iterator<Iter>
)
(function template)
(関数テンプレート)
乗法演算子
(関数テンプレート)
乗法演算子
(関数テンプレート)
(関数テンプレート)
ビット論理演算子
(public member function of
std::bitset<N>
)
(function template)
(public member function of
std::valarray<T>
)
(関数テンプレート)
ビットシフト演算子
(関数テンプレート)
(
std::bitset<N>
のパブリックメンバー関数) ストリーム挿入/抽出オペレータ
標準ライブラリを通して、ビットシフト演算子は一般的に I/O ストリームでオーバーロードされます(標準.steam.str)。:ios_base& またはそこから派生したクラスの 1 つ) を左オペランドと戻り値の型としてオーバーロードするのが一般的です。 このような演算子は、ストリーム挿入演算子およびストリーム抽出演算子として知られている。
(
std::basic_istream<CharT,Traits>
のパブリックメンバ関数)
(関数テンプレート)
(
std::basic_ostream<CharT,Traits>
のパブリックメンバ関数)
(関数テンプレート)
(関数テンプレート)
(関数テンプレート)
(関数テンプレート)
(function template)
(function template)
Defect reports
以下の動作を変更する欠陥レポートは以前に公開されたC++標準に遡及適用されました。
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 1457 | C++98 | made well Shift the leftmost bit of a posigned value in a sign bit is UB | made well C++98 |
See also
Operator precedence
Operator overloading
Common operators | ||||||
---|---|---|---|---|---|---|
assignment | インクリメント デクリメント |
算術 | 論理 | 比較 | メンバー アクセス |
その他 |
a = b |
++a |
+a |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!?a |
a == b |
a >b |
a(…) |
特殊演算子 | ||||||
static_cast ある型を別の関連する型に変換する |