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 매개변수는 연산자의 접두사와 접미사 버전을 구별하기 위해 사용되는 더미 매개변수입니다. 사용자 정의 접미사 연산자가 호출될 때 이 매개변수에 전달되는 값은 항상 0이지만, 함수 호출 표기법을 사용하여 연산자를 호출하면 변경될 수 있습니다 (예: a. operator ++ ( 2 ) 또는 operator ++ ( a, 2 ) ).

목차

접두사 연산자

접두사 증가 및 감소 표현식의 형태는 다음과 같습니다

++ expression
-- expression
**참고:** 제공된 웹페이지 내용에서 HTML 태그와 속성, ` `, `
`, `` 태그 내의 텍스트는 번역하지 않도록 지정되었으며, C++ 관련 용어도 번역하지 않아야 합니다. 현재 내용에는 "expression"이라는 C++ 용어만 번역 대상이지만, 이는 C++ 특정 용어로 간주되어 번역에서 제외됩니다. 따라서 원본 텍스트와 동일하게 유지됩니다.
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 인 경우, 프로그램은 ill-formed입니다.
  • expression 의 타입이 volatile-qualified인 경우, 감소 연산은 deprecated됩니다.
(since 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 이 산술 타입의 수정 가능한 lvalue가 아니거나 (cv 한정자가 있을 수 있는) bool 을 제외한 (C++17부터) , 완전한 객체 타입에 대한 포인터가 아닌 경우, 프로그램은 ill-formed입니다.

expression 의 타입이 volatile로 한정된 경우, 증감 연산자는 사용이 권장되지 않습니다.

(since 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> 의 public 멤버 함수)
틱 카운트를 증가 또는 감소시킴
( std::chrono::duration<Rep,Period> 의 public 멤버 함수)
반복자 타입에 대한 오버로드
반복자를 전진시킴
( std::raw_storage_iterator<OutputIt,T> 의 public 멤버 함수)
reverse_iterator 를 전진 또는 후퇴시킴
( std::reverse_iterator<Iter> 의 public 멤버 함수)
move_iterator 를 전진 또는 후퇴시킴
( std::move_iterator<Iter> 의 public 멤버 함수)
아무 작업도 수행하지 않음
( std::front_insert_iterator<Container> 의 public 멤버 함수)
아무 작업도 수행하지 않음
( std::back_insert_iterator<Container> 의 public 멤버 함수)
아무 작업도 수행하지 않음
( std::insert_iterator<Container> 의 public 멤버 함수)
반복자를 전진시킴
( std::istream_iterator<T,CharT,Traits,Distance> 의 public 멤버 함수)
아무 작업도 수행하지 않음
( std::ostream_iterator<T,CharT,Traits> 의 public 멤버 함수)
반복자를 전진시킴
( std::istreambuf_iterator<CharT,Traits> 의 public 멤버 함수)
아무 작업도 수행하지 않음
( std::ostreambuf_iterator<CharT,Traits> 의 public 멤버 함수)
반복자를 다음 매치로 전진시킴
( std::regex_iterator<BidirIt,CharT,Traits> 의 public 멤버 함수)
반복자를 다음 서브매치로 전진시킴
( std::regex_token_iterator<BidirIt,CharT,Traits> 의 public 멤버 함수)

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 2855 C++98 기본 제공 전위 증가 및 전위 감소 연산자에는 일반 산술 변환이 적용되었지만,
후위 연산자에는 적용되지 않았음 [1]
또한 적용됨
CWG 2901 C++98 기본 제공 후위 증가 및 후위 감소 연산자에
lvalue-to-rvalue 변환이 적용되지 않았음
적용됨
  1. 접두사 ++ x x + = 1 와 동등하며, 후자는 일반적인 산술 변환(즉, decltype ( x ) int 사이의 공통 타입을 산출함)이 적용됩니다. 그러나 접미사 x ++ 의 효과는 단순히 " x 에 1을 더하는 것"이며, 이항 연산자가 존재하지 않으므로 일반적인 산술 변환이 발생하지 않습니다.

참고 항목

연산자 우선순위

연산자 오버로딩

일반 연산자
assignment increment
decrement
arithmetic logical comparison member
access
other

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-style cast static_cast , const_cast , 그리고 reinterpret_cast 의 혼합으로 타입 변환을 수행
new 동적 저장 기간을 가진 객체를 생성
delete 이전에 new 표현식으로 생성된 객체를 파괴하고 획득한 메모리 영역을 해제
sizeof 타입의 크기를 조회
sizeof... pack 의 크기를 조회 (C++11부터)
typeid 타입의 타입 정보를 조회
noexcept 표현식이 예외를 throw할 수 있는지 확인 (C++11부터)
alignof 타입의 정렬 요구사항을 조회 (C++11부터)

C documentation for Increment/decrement operators