インクリメント/デクリメント演算子
インクリメント/デクリメント演算子は、オブジェクトの値をインクリメントまたはデクリメントします。
| 演算子名 | 構文 | オーバーロード可能 | プロトタイプの例 (class T の場合) | |
|---|---|---|---|---|
| クラス定義内 | クラス定義外 | |||
| 前置インクリメント | ++a
|
はい | T& T::operator++(); | T& operator++(T& a); |
| 前置デクリメント | --a
|
はい | T& T::operator--(); | T& operator--(T& a); |
| 後置インクリメント | a++
|
はい | T T::operator++(int); | T operator++(T& a, int); |
| 後置デクリメント | a--
|
はい | T T::operator--(int); | T operator--(T& a, int); |
| ||||
目次 |
[編集] 前置演算子
前置インクリメントおよびデクリメント式は次の形式を持ちます。
++ 式 |
|||||||||
-- 式 |
|||||||||
[編集] 組み込み前置演算子
|
(C++17まで) |
|
(C++17以降) |
|
(C++20以降) |
- 式の型が (おそらく cv 修飾された) bool の場合、プログラムは ill-formed です。
|
(C++20以降) |
[編集] オーバーロード
ユーザー定義演算子に対するオーバーロード解決では、bool 以外のすべての任意に volatile 修飾された算術型 A、およびすべての任意に volatile 修飾された任意に cv 修飾されたオブジェクト型へのポインタ P について、以下の関数シグネチャがオーバーロード解決に参加します。
| A& operator++(A&) |
||
| bool& operator++(bool&) |
(非推奨)(C++17まで) | |
| P& operator++(P&) |
||
| A& operator--(A&) |
||
| P& operator--(P&) |
||
[編集] 後置演算子
後置インクリメントおよびデクリメント式は次の形式を持ちます。
式 ++ |
|||||||||
式 -- |
|||||||||
[編集] 組み込み後置演算子
後置インクリメントまたはデクリメントの結果は、式に (変更前の)lvalue-to-rvalue変換を適用して得られる値です。結果の型は、式の型のcv非修飾バージョンです。
式が (おそらく cv 修飾された) bool 以外の算術型または完全なオブジェクト型へのポインタの変更可能な lvalue ではない場合(C++17以降)、プログラムは ill-formed です。
|
式の型が揮発性修飾されている場合、インクリメントまたはデクリメントは非推奨です。 |
(C++20以降) |
++ 演算子のオペランドであるかのように変更されます。-- 演算子のオペランドであるかのように変更されます。後置インクリメントまたはデクリメントの値計算は、式の変更より前にシーケンスされます。不確定な順序の関数呼び出しに関して、後置インクリメントまたはデクリメントの操作は単一の評価です。
[編集] オーバーロード
ユーザー定義演算子に対するオーバーロード解決では、bool 以外のすべての任意に volatile 修飾された算術型 A、およびすべての任意に volatile 修飾された任意に cv 修飾されたオブジェクト型へのポインタ 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<T> のパブリックメンバ関数) | |
| ティック数を増減する ( std::chrono::duration<Rep,Period> のパブリックメンバ関数) | |
イテレータ型に対するオーバーロード | |
| イテレータを進める ( std::raw_storage_iterator<OutputIt,T> のパブリックメンバ関数) | |
reverse_iterator を進めるかデクリメントする( std::reverse_iterator<Iter> のパブリックメンバ関数) | |
move_iteratorを進める、または減らす( std::move_iterator<Iter> のパブリックメンバ関数) | |
| 何も行わない ( std::front_insert_iterator<Container> のパブリックメンバ関数) | |
| 何も行わない ( std::back_insert_iterator<Container> のパブリックメンバ関数) | |
| 何も行わない ( std::insert_iterator<Container> のパブリックメンバ関数) | |
| イテレータを進める ( std::istream_iterator<T,CharT,Traits,Distance> のパブリックメンバ関数) | |
| 何も行わない ( std::ostream_iterator<T,CharT,Traits> のパブリックメンバ関数) | |
| イテレータを進める ( std::istreambuf_iterator<CharT,Traits> のパブリックメンバ関数) | |
| 何も行わない ( std::ostreambuf_iterator<CharT,Traits> のパブリックメンバ関数) | |
| イテレータを次のマッチに進める ( std::regex_iterator<BidirIt,CharT,Traits> のパブリックメンバ関数) | |
| イテレータを次のサブマッチに進める ( std::regex_token_iterator<BidirIt,CharT,Traits> のパブリックメンバ関数) | |
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 2855 | C++98 | 組み込みの前置インクリメントおよび 前置デクリメントには通常の算術変換が適用されるが、後置の対応物には適用されなかった[1] |
も適用される |
| CWG 2901 | C++98 | 組み込みの後置インクリメントおよび後置デクリメントには lvalue-to-rvalue 変換が適用されなかった |
適用済み |
- ↑ 前置 ++x は x += 1 と同等であり、後者は通常の算術変換 (すなわち、decltype(x) と int の間の共通の型を生成する) が適用可能です。しかし、後置 x++ の効果は単に「x に1を加える」ことであり、二項演算子が存在しないため、通常の算術変換は行われません。
[編集] 関連項目
| 共通の演算子 | ||||||
|---|---|---|---|---|---|---|
| 代入 | インクリメント デクリメント |
算術 | 論理 | 比較 | メンバ アクセス |
その他 |
|
a = b |
++a |
+a |
!a |
a == b |
a[...] |
関数呼び出し a(...) |
| コンマ a, b | ||||||
| conditional a ? b : c | ||||||
| 特殊な演算子 | ||||||
|
static_castは、ある型を関連する別の型に変換する | ||||||
| C ドキュメント (インクリメント/デクリメント演算子)
|