Namespaces
Variants

Increment/decrement operators

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

演算子名 構文 オーバーロード可能 プロトタイプ例 ( 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 ) ;
注記
  • 組み込み演算子の前置バージョンは 参照 を返し、後置バージョンは を返します。一般的な ユーザー定義オーバーロード もこのパターンに従い、ユーザー定義演算子を組み込み演算子と同じ方法で使用できるようにします。ただし、ユーザー定義の演算子オーバーロードでは、あらゆる型を戻り値の型として使用できます( void を含む)。
  • int パラメータは、前置バージョンと後置バージョンの演算子を区別するために使用されるダミーパラメータです。ユーザー定義の後置演算子が呼び出されるとき、このパラメータに渡される値は常にゼロですが、関数呼び出し記法を使用して演算子を呼び出すことで変更される可能性があります(例: a. operator ++ ( 2 ) または operator ++ ( a, 2 ) )。

目次

前置演算子

前置インクリメントおよびデクリメント式の形式は以下の通りです

++
--
1) 前置インクリメント (pre-increment)
2) 前置デクリメント (pre-decrement)

組み込み前置演算子

1) ++ x は以下の例外を除き、 x + = 1 と等価です:
  • expression の型が(volatile修飾された可能性のある) bool の場合、 expression true に設定されます。このようなインクリメントは非推奨です。
(C++17まで)
  • expression の型が(cv修飾された可能性のある) bool の場合、プログラムは不適格です。
(C++17以降)
  • expression の型がvolatile修飾されている場合、インクリメントは非推奨です。
(C++20以降)
2) -- x は以下を除いて x - = 1 と等価です:
  • expression の型が(possibly cv-qualified) bool の場合、プログラムは不適格です。
  • expression の型がvolatile修飾されている場合、デクリメントは非推奨です。
(C++20以降)

オーバーロード

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

A & operator ++ ( A & )
bool & operator ++ ( bool & )
(非推奨) (C++17まで)
P & operator ++ ( P & )
A & operator -- ( A & )
P & operator -- ( P & )

後置演算子

後置インクリメントおよびデクリメント式は次の形式を持ちます

++
--
1) 後置インクリメント (post-increment)
2) 後置デクリメント (post-decrement)

組み込み後置演算子

後置インクリメントまたはデクリメントの結果は、 lvalue-to-rvalue conversion expression (変更前)に適用して得られる値です。結果の型は、 expression の型のcv-unqualified版です。

expression が算術型の変更可能な左値でない場合 ((possibly cv-qualified) bool を除く) (C++17以降) 、または完全オブジェクト型へのポインタでない場合、プログラムは不適格です。

expression の型がvolatile修飾されている場合、インクリメントまたはデクリメントは非推奨です。

(C++20以降)
1) 式の値は、前置 ++ 演算子のオペランドであるかのように変更されます。
2) 式の値は、前置 -- 演算子のオペランドであるかのように変更されます。

後置インクリメントまたはデクリメントの値計算は、 sequenced before expression の変更よりも前に順序付けられます。不定順序関数呼び出しに関して、後置インクリメントまたはデクリメントの操作は単一の評価です。

オーバーロード

ユーザー定義演算子に対するオーバーロード解決 において、 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 -- をオーバーロードします。たとえそれらの演算子が特定のイテレータに対してno-opであっても同様です。

算術型に対するオーバーロード
アトミック値を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> の公開メンバ関数)
何もしない(no-op)
( std::front_insert_iterator<Container> の公開メンバ関数)
何もしない(no-op)
( std::back_insert_iterator<Container> の公開メンバ関数)
何もしない(no-op)
( std::insert_iterator<Container> の公開メンバ関数)
イテレータを進める
( std::istream_iterator<T,CharT,Traits,Distance> の公開メンバ関数)
何もしない(no-op)
( std::ostream_iterator<T,CharT,Traits> の公開メンバ関数)
イテレータを進める
( std::istreambuf_iterator<CharT,Traits> の公開メンバ関数)
何もしない(no-op)
( 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 組み込みの後置インクリメントと後置デクリメントに
左辺値から右辺値への変換が適用されなかった
適用
  1. 前置 ++ x x + = 1 と等価であり、後者は通常の算術変換(すなわち decltype ( x ) int の共通型を生成する)が適用可能です。しかしながら、後置 x ++ の効果は単に「 x に1を加算する」というものであり、二項演算子が存在しないため、通常の算術変換は行われません。

関連項目

演算子の優先順位

演算子のオーバーロード

翻訳の説明: - 「comma」を「カンマ」に翻訳 - HTMLタグ、属性はそのまま保持 - ` `タグ内のC++コード「a, b」は翻訳せず保持 - すべての書式設定と構造を正確に維持 **翻訳の説明:** - "conditional" → "条件演算子"(C++の三項演算子の正式名称) - HTMLタグ、属性、 内の記号(?と:)はそのまま保持 - C++コード部分(a, b, c)は翻訳せず保持 - フォーマットと構造は完全に維持
共通演算子
代入 インクリメント
デクリメント
算術 論理 比較 メンバー
アクセス
その他

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

関数呼び出し

a ( ... )
カンマ

a, b
条件演算子

a ? b : c
特殊演算子

static_cast 関連する型間での変換を行う
dynamic_cast 継承階層内での変換を行う
const_cast cv 修飾子の追加または削除を行う
reinterpret_cast 無関係な型間での変換を行う
Cスタイルキャスト static_cast , const_cast , および reinterpret_cast の組み合わせで型変換を行う
new 動的ストレージ期間を持つオブジェクトを作成する
delete new式で作成されたオブジェクトを破棄し、取得したメモリ領域を解放する
sizeof 型のサイズを問い合わせる
sizeof... パック のサイズを問い合わせる (C++11以降)
typeid 型の型情報を問い合わせる
noexcept 式が例外を送出できるかどうかをチェックする (C++11以降)
alignof 型のアライメント要件を問い合わせる (C++11以降)

C documentation for Increment/decrement operators
日本語訳:
C documentation for インクリメント/デクリメント演算子
HTMLタグ、属性、C++固有の用語("C documentation")は翻訳せず、テキスト部分のみを正確に日本語化しました。