Assignment operators
대입 연산자는 객체의 값을 수정합니다.
| 연산자 이름 | 구문 | 오버로드 가능 | 프로토타입 예시 ( class T 에 대해) | |
|---|---|---|---|---|
| 클래스 정의 내부 | 클래스 정의 외부 | |||
| 단순 할당 |
a = b
|
예 | T & T :: operator = ( const T2 & b ) ; | 해당 없음 |
| 덧셈 할당 |
a += b
|
예 | T & T :: operator + = ( const T2 & b ) ; | T & operator + = ( T & a, const T2 & b ) ; |
| 뺄셈 할당 |
a -= b
|
예 | T & T :: operator - = ( const T2 & b ) ; | T & operator - = ( T & a, const T2 & b ) ; |
| 곱셈 할당 |
a *= b
|
Yes | T & T :: operator * = ( const T2 & b ) ; | T & operator * = ( T & a, const T2 & b ) ; |
| 나눗셈 할당 |
a /= b
|
지원 | T & T :: operator / = ( const T2 & b ) ; | T & operator / = ( T & a, const T2 & b ) ; |
| 나머지 할당 |
a %= b
|
Yes | T & T :: operator % = ( const T2 & b ) ; | T & operator % = ( T & a, const T2 & b ) ; |
| 비트 AND 할당 |
a &= b
|
Yes | T & T :: operator & = ( const T2 & b ) ; | T & operator & = ( T & a, const T2 & b ) ; |
| 비트 OR 할당 |
a |= b
|
Yes | T & T :: operator | = ( const T2 & b ) ; | T & operator | = ( T & a, const T2 & b ) ; |
| 비트 XOR 할당 |
a ^= b
|
예 | T & T :: operator ^ = ( const T2 & b ) ; | T & operator ^ = ( T & a, const T2 & b ) ; |
| 비트 왼쪽 시프트 할당 |
a <<= b
|
예 | T & T :: operator <<= ( const T2 & b ) ; | T & operator <<= ( T & a, const T2 & b ) ; |
| 비트 단위 오른쪽 시프트 할당 |
a >>= b
|
예 | T & T :: operator >>= ( const T2 & b ) ; | T & operator >>= ( T & a, const T2 & b ) ; |
|
||||
목차 |
정의
복사 할당 은 객체 a 의 내용을 b 의 내용 복사본으로 대체합니다( b 는 수정되지 않음). 클래스 타입의 경우, 이는 복사 할당 연산자 에서 설명되는 특별 멤버 함수에서 수행됩니다.
|
이동 대입 은 객체 a 의 내용을 b 의 내용으로 대체하며, 가능한 경우 복사를 피합니다( b 는 수정될 수 있음). 클래스 타입의 경우, 이는 이동 대입 연산자 에서 설명된 특별 멤버 함수에서 수행됩니다. |
(C++11부터) |
비클래스 타입의 경우, 복사 할당과 이동 할당은 구분할 수 없으며 직접 할당 으로 지칭됩니다.
복합 할당 은 객체 a 의 내용을 a 의 이전 값과 b 의 값 사이의 이항 연산 결과로 대체합니다.
대입 연산자 구문
대입 표현식의 형식은 다음과 같습니다
target-expr
=
new-value
|
(1) | ||||||||
| target-expr op new-value | (2) | ||||||||
| target-expr | - | 할당될 표현식 [1] |
| op | - | 다음 중 하나 * = , / = % = , + = - = , <<= , >>= , & = , ^ = , | = |
| new-value | - | 대상에 할당할 표현식 [2] (C++11 이전) 초기화 절 (C++11 이후) |
|
만약 new-value 가 표현식이 아니라면, 할당 표현식은 오버로드된 복합 할당 연산자와 절대 일치하지 않습니다. |
(since C++11) |
내장 단순 할당 연산자
내장 단순 대입의 경우, target-expr 는 수정 가능한 lvalue여야 합니다.
target-expr
이 참조하는 객체는 그 값이
new-value
의 결과로 대체되어 수정됩니다. 참조된 객체가 정수 타입
T
이고,
new-value
의 결과가 해당 부호 있는/없는 정수 타입인 경우, 객체의 값은
new-value
결과와 동일한 값 표현을 갖는
T
타입의 값으로 대체됩니다.
내장 단순 할당의 결과는 target-expr 의 타입에 대한 lvalue이며, target-expr 을 참조합니다. 만약 target-expr 이 비트 필드 라면, 결과 또한 비트 필드입니다.
표현식으로부터의 할당
만약 new-value 가 표현식인 경우, 이는 암시적으로 변환 되어 target-expr 의 cv-unqualified 타입으로 변환됩니다. target-expr 이 표현식의 값을 표현할 수 없는 비트 필드인 경우, 비트 필드의 결과 값은 구현에 따라 정의됩니다.
만약 target-expr 과 new-value 가 겹치는 객체를 식별하는 경우, 동작은 정의되지 않습니다 (겹침이 정확하고 타입이 동일한 경우는 제외).
|
target-expr 의 타입이 volatile로 한정된 경우, (괄호로 둘러싸인 경우를 포함한) 할당 표현식이 폐기값 표현식(discarded-value expression) 이거나 평가되지 않는 피연산자(unevaluated operand) 인 경우를 제외하고, 할당은 사용이 권장되지 않음(deprecated). |
(C++20부터) |
비표현식 초기화 절로부터의 할당new-value 가 표현식이 아닌 것이 허용되는 경우는 다음과 같은 상황에서만입니다:
#include <complex> std::complex<double> z; z = {1, 2}; // meaning z.operator=({1, 2}) z += {1, 2}; // meaning z.operator+=({1, 2}) int a, b; a = b = {1}; // meaning a = b = 1; a = {1} = b; // syntax error |
(C++11부터) |
사용자 정의 연산자에 대한 오버로드 해결
에서, 모든 타입
T
에 대해 다음 함수 시그니처들이 오버로드 해결에 참여합니다:
|
T
*
&
operator
=
(
T
*
&
, T
*
)
;
|
||
|
T
*
volatile
&
operator
=
(
T
*
volatile
&
, T
*
)
;
|
||
모든 열거형 또는 멤버 포인터 타입
T
에 대해, 선택적으로 volatile 한정된 경우, 다음 함수 시그니처가 오버로드 해결에 참여합니다:
|
T
&
operator
=
(
T
&
, T
)
;
|
||
모든
A1
과
A2
쌍에 대해, 여기서
A1
은 산술 타입(선택적으로 volatile 한정자 포함)이고
A2
는 승격된 산술 타입인 경우, 다음 함수 시그니처가 오버로드 해결에 참여합니다:
|
A1
&
operator
=
(
A1
&
, A2
)
;
|
||
내장 복합 할당 연산자
모든 내장 복합 할당 표현식
target-expr
op
=
new-value
의 동작은 표현식
target-expr
=
target-expr
op
new-value
의 동작과 정확히 동일합니다. 단,
target-expr
이(가) 한 번만 평가된다는 점이 다릅니다.
내장 단순 할당 연산자의 target-expr 과 new-value 에 대한 요구사항들도 동일하게 적용됩니다. 또한:
-
+=및-=연산자의 경우, target-expr 의 타입은 arithmetic type 이거나 (possibly cv-qualified) completely-defined object type 에 대한 포인터여야 합니다. - 다른 모든 복합 할당 연산자의 경우, target-expr 의 타입은 arithmetic type이어야 합니다.
사용자 정의 연산자에 대한 오버로드 해결
에서, 모든
A1
과
A2
쌍에 대해, 여기서
A1
은 산술 타입(선택적으로 volatile 한정자 가능)이고
A2
는 승격된 산술 타입인 경우, 다음 함수 시그니처들이 오버로드 해결에 참여합니다:
|
A1
&
operator
*
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operator
/
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operator
+
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operator
-
=
(
A1
&
, A2
)
;
|
||
모든
I1
과
I2
쌍에 대해, 여기서
I1
은 정수형(선택적으로 volatile 한정자 포함)이고
I2
는 승격된 정수형일 때, 다음 함수 시그니처들이 오버로드 해결에 참여합니다:
|
I1
&
operator
%
=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
<<=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
>>=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
&
=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
^
=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
|
=
(
I1
&
, I2
)
;
|
||
모든 선택적으로 cv 한정된 객체 타입
T
에 대해, 다음 함수 시그니처들이 오버로드 해결에 참여합니다:
|
T
*
&
operator
+
=
(
T
*
&
,
std::
ptrdiff_t
)
;
|
||
|
T
*
&
operator
-
=
(
T
*
&
,
std::
ptrdiff_t
)
;
|
||
|
T
*
volatile
&
operator
+
=
(
T
*
volatile
&
,
std::
ptrdiff_t
)
;
|
||
|
T
*
volatile
&
operator
-
=
(
T
*
volatile
&
,
std::
ptrdiff_t
)
;
|
||
예제
#include <iostream> int main() { int n = 0; // 대입이 아님 n = 1; // 직접 대입 std::cout << n << ' '; n = {}; // 0 초기화 후 대입 std::cout << n << ' '; n = 'a'; // 정수 승격 후 대입 std::cout << n << ' '; n = {'b'}; // 명시적 변환 후 대입 std::cout << n << ' '; n = 1.0; // 부동소수점 변환 후 대입 std::cout << n << ' '; // n = {1.0}; // 컴파일러 오류 (축소 변환) int& r = n; // 대입이 아님 r = 2; // 참조를 통한 대입 std::cout << n << ' '; int* p; p = &n; // 직접 대입 p = nullptr; // 널 포인터 변환 후 대입 std::cout << p << ' '; struct { int a; std::string s; } obj; obj = {1, "abc"}; // 중괄호 초기화 목록에서의 대입 std::cout << obj.a << ':' << obj.s << '\n'; }
가능한 출력:
1 0 97 98 1 2 (nil) 1:abc
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 1527 | C++11 |
클래스 타입 객체에 대한 할당 시, 우측 피연산자는
사용자 정의 할당 연산자로 정의된 경우에만 초기화 리스트가 될 수 있었음 |
사용자 정의 할당
제약 조건 제거됨 |
| CWG 1538 | C++11 |
E1
=
{
E2
}
는
E1
=
T
(
E2
)
와 동등했으며,
이는 C-스타일 캐스트를 도입함 (
T
는
E1
의 타입)
|
다음 표현식과
동등함: E1 = T { E2 } |
| CWG 2654 | C++20 |
volatile 한정 타입에 대한 복합 할당 연산자가
일관성 없이 사용 중단됨 |
모두 사용 중단
되지 않음 |
| CWG 2768 | C++11 |
비표현식 초기화 절에서 스칼라 값으로의 할당이
직접 목록 초기화를 수행했음 |
대신 복사 목록
초기화를 수행함 |
| CWG 2901 | C++98 |
int
lvalue를 통해
unsigned
int
객체에
할당된 값이 불명확했음 |
명확해짐 |
| P2327R1 | C++20 |
volatile 타입에 대한 비트 단위 복합 할당 연산자가
일부 플랫폼에서 유용함에도 사용 중단됨 |
사용 중단
되지 않음 |
참고 항목
| 일반 연산자 | ||||||
|---|---|---|---|---|---|---|
| assignment |
increment
decrement |
arithmetic | logical | comparison |
member
access |
other |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
...
]
|
함수 호출
a ( ... ) |
|
콤마
a, b |
||||||
|
조건부 연산자
a ? b : c |
||||||
| 특수 연산자 | ||||||
|
static_cast
관련된 타입 간 변환을 수행
|
||||||
|
C 문서
참조:
대입 연산자
|