'? :'의 반환 유형 (삼항 조건 연산자)
첫 번째가 왜 참조를 반환합니까?
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를 리턴 할 수 없습니다 .x
y
:
표준은 무엇을 말합니까? ( 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
'IT story' 카테고리의 다른 글
Excel의 수식에서 빈 셀 반환 (0) | 2020.05.05 |
---|---|
엡실론을 사용하여 double을 0으로 비교 (0) | 2020.05.05 |
새로운 PostgreSQL JSON 데이터 유형의 필드를 사용하여 쿼리하려면 어떻게합니까? (0) | 2020.05.05 |
파이썬에서 멀티 프로세싱을 사용하는 동안 어떻게 로그인해야합니까? (0) | 2020.05.05 |
ASP.NET MVC에서 요청 조절을 구현하는 가장 좋은 방법은 무엇입니까? (0) | 2020.05.05 |