IT story

'? :'의 반환 유형 (삼항 조건 연산자)

hot-time 2020. 5. 5. 19:38
반응형

'? :'의 반환 유형 (삼항 조건 연산자)


첫 번째가 왜 참조를 반환합니까?

int x = 1;
int y = 2;
(x > y ? x : y) = 100;

두 번째는 그렇지 않지만?

int x = 1;
long y = 2;
(x > y ? x : y) = 100;

실제로 두 번째는 전혀 할당되지 않았습니다.


식에는 반환 형식이 없으며 형식이 있으며 최신 C ++ 표준에서 알려진 것처럼 값 범주가 있습니다.

조건식은 lvalue 또는 rvalue 일 수 있습니다 . 이것이 가치 범주입니다. ( C++11우리는 lvalues, xvalues ​​및 prvalues 가 있기 때문에 다소 단순화 된 것입니다.)

매우 광범위하고 간단한 용어로, lvalue 는 메모리의 객체를 나타내며 rvalue메모리의 객체에 반드시 연결될 필요는없는 값일뿐입니다.

대입 식은 객체에 값을 대입하므로 할당되는 것은 lvalue 이어야합니다 .

조건식 ( ?:)이 lvalue (넓고 간단한 용어로)가 되려면 두 번째와 세 번째 피연산자가 같은 유형의 lvalue 여야합니다 . 조건부 표현식의 유형 및 값 범주는 컴파일시 결정되며 조건이 true인지 여부에 따라 적절해야하기 때문입니다. 피연산자 중 하나가 다른 일치하는 다른 형식으로 변환해야하는 경우 다음 조건식은 될 수 없다 좌변 되지 않을 것이 변환의 결과로 좌변 .

ISO / IEC 14882 : 2011 참조 :

3.10 [basic.lval] L 값 및 r 값 (값 범주 정보)

5.15 [expr.cond] 조건부 연산자 (조건부 표현식의 유형 및 값 범주에 대한 규칙)

5.17 [expr.ass] 대입 및 복합 대입 연산자 (대입의 lhs는 수정 가능한 lvalue 여야 함)


삼항 ?:표현식의 유형은 두 번째 및 세 번째 인수의 공통 유형입니다. 두 유형이 모두 같으면 참조가 다시 제공됩니다. 서로 전환 할 수있는 경우 하나를 선택하고 다른 하나를 변환합니다 (이 경우 승격). 임시 (변환 / 승격 된 변수)에 대한 lvalue 참조를 리턴 할 수 없으므로 해당 유형은 값 유형입니다.


유형이 일치하도록 유형 을 암시 적으로 승격시켜야하고 (양측이 동일한 유형이 아니기 때문에 ) 임시 값을 작성 해야하므로 lvalue를 리턴 할 수 없습니다 .xy:


표준은 무엇을 말합니까? ( n1905 )

식 5.17 대입 및 복합 대입 연산자

5.17 / 3

두 번째와 세 번째 피연산자가 서로 다른 유형을 가지고 있고 클래스 유형 (아마도 cv-qualified)이있는 경우, 각 피연산자 각각을 다른 유형으로 변환하려고 시도합니다. 유형 T1의 피연산자 표현식 E1이 유형 T2의 피연산자 표현식 E2와 일치하도록 변환 될 수 있는지 여부를 판별하는 프로세스는 다음과 같이 정의됩니다.

— E2가 lvalue 인 경우 : E1을 암시 적으로 "T2에 대한 참조"유형으로 변환 할 수있는 경우 E1을 E2와 일치하도록 변환 할 수 있습니다 (변환에서 참조가 직접 바인딩되어야 함 (8.5.3)). )를 E1에

— E2가 rvalue이거나 위의 변환을 수행 할 수없는 경우 :

— E1과 E2에 클래스 유형이 있고 기본 클래스 유형이 같거나 하나가 다른 클래스의 기본 클래스 인 경우 : T2 클래스와 유형이 같거나 E2의 기본 클래스 인 경우 E1은 E2와 일치하도록 변환 될 수 있습니다. , T1의 클래스 및 T2의 cv-qualification은 T1의 cv-qualification과 동일한 cv-qualification이거나 더 큰 cv-qualification입니다. 변환이 적용되는 경우, E1은 원래 소스 클래스 오브젝트 (또는 해당 하위 오브젝트)를 여전히 참조하는 T2 유형의 rvalue로 변경됩니다. [ 참고 : 즉, 복사가 이루어지지 않습니다. — end note ] E1에서 T2 유형의 임시를 복사 초기화하고 해당 임시를 변환 된 피연산자로 사용합니다.

그렇지 않은 경우 (예 : E1또는 E2에 클래스 유형이 아닌 경우 또는 둘 다 클래스 유형이 있지만 기본 클래스가 같거나 다른 클래스의 기본 클래스가 아닌 경우) : E1이 가능한 경우 E1은 E2와 일치하도록 변환 될 수 있습니다. E2가 rvalue로 변환 된 경우 표현식 E2가 갖는 유형 (또는 E2가 rvalue 인 경우 보유한 유형)으로 내재적으로 변환됩니다.

이 프로세스를 사용하여, 제 2 피연산자가 제 3 피연산자와 일치하도록 변환 될 수 있는지, 그리고 제 3 피연산자가 제 2 피연산자와 일치하도록 변환 될 수 있는지 여부가 결정된다. 둘 다 변환 할 수 있거나 변환 할 수 있지만 변환이 모호한 경우 프로그램이 잘못 구성됩니다. 둘 다 변환 할 수없는 경우 피연산자는 변경되지 않은 상태로 유지되며 아래에 설명 된대로 추가 검사가 수행됩니다. 정확히 하나의 변환이 가능한 경우 해당 변환이 선택한 피연산자에 적용되고 변환 된 피연산자가이 섹션의 나머지 부분에 대해 원래 피연산자 대신 사용됩니다.


5.17 / 4

두 번째 및 세 번째 피연산자가 lvalues이고 동일한 유형을 갖는 경우 결과는 해당 유형이며 lvalue이며 두 번째 또는 세 번째 피연산자가 비트 필드이거나 둘 다 비트 인 경우 비트 필드입니다. 필드.


5.17 / 5

Otherwise, the result is an rvalue. If the second and third operands do not have the same type, and either has (possibly cv-qualified) class type, overload resolution is used to determine the conversions (if any) to be applied to the operands (13.3.1.2, 13.6). If the overload resolution fails, the program is ill-formed. Otherwise, the conversions thus determined are applied, and the converted operands are used in place of the original operands for the remainder of this section.

참고URL : https://stackoverflow.com/questions/8535226/return-type-of-ternary-conditional-operator

반응형