名前空間
変種
操作

インクリメント/デクリメント演算子

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (C++20未満)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
一般
値カテゴリ (lvalue, rvalue, xvalue)
評価順序 (副作用完了点)
定数式
未評価式
一次式
ラムダ式(C++11)
リテラル
整数リテラル
浮動小数点リテラル
ブーリアンリテラル
文字リテラル および エスケープシーケンス
文字列リテラル
ヌルポインタリテラル(C++11)
ユーザ定義リテラル(C++11)
演算子
代入演算子: 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)
メンバアクセス演算子: a[b], *a, &a, a->b, a.b, a->*b, a.*b
その他の演算子: a(...), a,b, a?b:c
デフォルト比較(C++20)
演算子の代替表現
優先順位と結合性
畳み込み式(C++17)
new 式
delete 式
throw 式
alignof
sizeof
sizeof...(C++11)
typeid
noexcept(C++11)
演算子オーバーロード
変換
暗黙の変換
const_cast
static_cast
reinterpret_cast
dynamic_cast
明示的な変換 (T)a, T(a)
ユーザ定義変換
 

インクリメント/デクリメント演算子はオブジェクトの値をインクリメントまたはデクリメントします。

演算子の名前 構文 オーバーロード可能 プロトタイプの例 (class T に対して)
クラス定義の内側 クラス定義の外側
前置インクリメント ++a Yes T& T::operator++(); T& operator++(T& a);
前置デクリメント --a Yes T& T::operator--(); T& operator--(T& a);
後置インクリメント a++ Yes T T::operator++(int); T operator++(T& a, int);
後置デクリメント a-- Yes T T::operator--(int); T operator--(T& a, int);
注釈
  • 組み込みの演算子の前置バージョンは参照を返し、後置バージョンはを返します。 一般的なユーザ定義のオーバーロードは、組み込みのものと同じ方法で使用できるように、このパターンに従っています。 しかしユーザ定義の演算子オーバーロードでは任意の型 (void を含む) を戻り値の型として使用することができます。
  • int 引数は演算子の前置バージョンと後置バージョンを区別するために使用されるダミー引数です。 ユーザ定義の後置演算子が呼ばれるとき、この引数に渡される値は常にゼロですが、関数呼び出し表記 (a.operator++(2)operator++(a, 2) など) を使用して演算子を呼ぶと変わることはあります。

目次

[編集] 説明

前置インクリメントおよび前置デクリメント演算子はオブジェクトの値をインクリメントまたはデクリメントし、その結果への参照を返します。

後置インクリメントおよび後置デクリメントはオブジェクトのコピーを作成し、オブジェクトの値をインクリメントまたはデクリメントし、そのインクリメントまたはデクリメントの前のコピーを返します。

[編集] 組み込みの前置演算子

前置インクリメントおよびデクリメント式は以下の形式を持ちます。

++ expr
-- expr
1) 前置インクリメント。
2) 前置デクリメント。

組み込みの前置インクリメントまたはデクリメント演算子の被演算子 expr は、ブーリアンでない算術型、または完全オブジェクト型へのポインタの、変更可能な (const でない) 左辺値でなければなりません。 ブーリアンでない被演算子の場合、式 ++xx += 1 とまったく同等であり、式 --xx -= 1 とまったく同等です。 つまり、前置インクリメントまたはデクリメントは、変更された被演算子を表す左辺値式です。 算術演算子に対して定義されているすべての算術変換のルールおよびポインタ算術のルールが適用され、被演算子および式の戻り値の型に適用される暗黙の変換 (もしあれば) を決定します。

前置インクリメント演算子の被演算子が bool 型の場合、それは true に設定されます。(非推奨) (C++17未満)

ユーザ定義の演算子に対するオーバーロード解決において、 bool 以外のすべての算術型 (およびその volatile 修飾された型) A に対して、およびオブジェクト型 (およびその cv 修飾された型) へのすべてのポインタ (および volatile 修飾されたポインタ) P に対して、以下の関数シグネチャがオーバーロード解決に参加します。

A& operator++(A&)
bool& operator++(bool&)
(非推奨)(C++17未満)
P& operator++(P&)
A& operator--(A&)
P& operator--(P&)

[編集] 組み込みの後置演算子

後置インクリメントおよびデクリメント演算子式は以下の形式を持ちます。

expr ++
expr --
1) 後置インクリメント。
2) 後置デクリメント。

組み込みの後置インクリメントまたはデクリメント演算子は、ブーリアンでない算術型、または完全オブジェクト型へのポインタの、変更可能な (const でない) 左辺値でなければなりません。 結果は被演算子の元の値のコピーの prvalue です。 副作用として、ブーリアンでない演算子の場合、式 x++x += 1 を評価したかのように被演算子の値を変更し、式 x--x -= 1 を評価したかのように被演算子の値を変更します。 算術演算子に対して定義されているすべての算術変換のルールおよびポインタ算術のルールが適用され、被演算子および式の戻り値の型に適用される暗黙の変換 (もしあれば) を決定します。

後置インクリメント演算子の被演算子が bool 型の場合、それは true に設定されます。(非推奨) (C++17未満)

ユーザ定義の演算子に対するオーバーロード解決において、 bool 以外のすべての算術型 (およびその volatile 修飾された型) A に対して、およびオブジェクト型 (またはその cv 修飾された型) へのポインタ (および volatile 修飾されたポインタ) P に対して、以下の関数シグネチャがオーバーロード解決に参加します。

A operator++(A&, int)
bool operator++(bool&, int)
(非推奨)(C++17未満)
P operator++(P&, int)
A operator--(A&, int)
P operator--(P&, int)

[編集]

#include <iostream>
 
int main()
{
    int n1 = 1;
    int n2 = ++n1;
    int n3 = ++ ++n1;
    int n4 = n1++;
//  int n5 = n1++ ++;   // error
//  int n6 = n1 + ++n1; // undefined behavior
    std::cout << "n1 = " << n1 << '\n'
              << "n2 = " << n2 << '\n'
              << "n3 = " << n3 << '\n'
              << "n4 = " << n4 << '\n';
}

出力:

n1 = 5
n2 = 2
n3 = 4
n4 = 4

[編集] ノート

発生する副作用のため、組み込みのインクリメントおよびデクリメント演算子は、評価順序のルールの違反による未定義動作を避けるために、注意して使用しなければなりません。

後置インクリメントおよび後置デクリメント中にオブジェクトの一時コピーが構築されるため、返される値が使用されない文脈では、通常、前置インクリメントまたは前置デクリメント演算子の方が効率的です。

[編集] 標準ライブラリ

インクリメントおよびデクリメント演算子は標準ライブラリの多くの型に対してオーバーロードされています。 特に、すべての LegacyIterator は operator++ をオーバーロードし、すべての LegacyBidirectionalIterator は operator-- をオーバーロードします (たとえ特定のイテレータについてはこれらの演算子が無操作であっても)。

算術型に対するオーバーロード
アトミック値を1つインクリメントまたはデクリメントします
(std::atomicのパブリックメンバ関数) [edit]
刻み数をインクリメントまたはデクリメントします
(std::chrono::durationのパブリックメンバ関数) [edit]
イテレータ型に対するオーバーロード
イテレータを進めます
(std::raw_storage_iteratorのパブリックメンバ関数) [edit]
イテレータをインクリメントもしくはデクリメントします
(std::reverse_iteratorのパブリックメンバ関数) [edit]
イテレータをインクリメントもしくはデクリメントします
(std::move_iteratorのパブリックメンバ関数) [edit]
何もしません
(std::front_insert_iteratorのパブリックメンバ関数) [edit]
何もしません
(std::back_insert_iteratorのパブリックメンバ関数) [edit]
何もしません
(std::insert_iteratorのパブリックメンバ関数) [edit]
イテレータを進めます
(std::istream_iteratorのパブリックメンバ関数) [edit]
何もしません
(std::ostream_iteratorのパブリックメンバ関数) [edit]
イテレータを進めます
(std::istreambuf_iteratorのパブリックメンバ関数) [edit]
何もしません
(std::ostreambuf_iteratorのパブリックメンバ関数) [edit]
イテレータを次のマッチに進めます
(std::regex_iteratorのパブリックメンバ関数) [edit]
イテレータを次の部分マッチに進めます
(std::regex_token_iteratorのパブリックメンバ関数) [edit]

[編集] 関連項目

演算子の優先順位

演算子オーバーロード

一般的な演算子
代入 インクリメント
デクリメント
算術 論理 比較 メンバアクセス その他

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[b]
*a
&a
a->b
a.b
a->*b
a.*b

a(...)
a, b
? :

特殊な演算子

static_cast は型を別の関連する型に変換します。
dynamic_cast は継承階層内で変換します。
const_castcv 修飾子を追加または削除します。
reinterpret_cast は型を無関係の型に変換します。
C スタイルのキャストstatic_cast, const_cast, reinterpret_cast の混合によって型を別の型に変換します。
new は動的記憶域期間を持つオブジェクトを作成します。
delete は以前に new 式によって作成されたオブジェクトを破棄し、取得したメモリ領域を解放します。
sizeof は型のサイズを照会します。
sizeof...パラメータパックのサイズを照会します。 (C++11以上)
typeid は型の型情報を照会します。
noexcept は式が例外を投げることができるかどうかを調べます。 (C++11以上)
alignof は型のアライメント要件を照会します。 (C++11以上)

インクリメント/デクリメント演算子C言語リファレンス