문제

내가 정말로 원하는 것은 || = 운영자입니다.

old_value = old_value || possible_new_value;
old_value ||= possible_new_value;

두 번째 줄은 컴파일러 오류입니다 (C ++에는 || = 연산자가 없습니다).

그래서 내 다른 옵션은 무엇입니까?

old_value += possible_new_value;
old_value |= possible_new_value;

내가 피사체에있는 동안 Bool은 다른 비 불리 사업자와 어떻게 행동합니까?

-
-=
&
&=
...

나는 이것들을 경험적으로 확인할 수 있지만 표준의 말에 가장 관심이 있습니다.

도움이 되었습니까?

해결책

4.7 (통합 변환)에 따르면 4.6 항에 따르면 "대상 유형이 bool, 4.12 참조. 소스 유형이있는 경우 bool, 가치 false 0과 값으로 변환됩니다 true "4.12에서"산술, 열거, 포인터 또는 멤 bool. 0 값, 널 포인터 값 또는 널 멤버 포인터 값이 변환됩니다. false; 다른 값이 변환됩니다 true."

상황에서 bool 피연산자는 허용되지 않지만 필수 피연산자는 bool 적분 유형으로 변환됩니다. 정수 결과가 a에 저장 될 때 bool 변수는 변환됩니다 bool.

따라서 + 및 *를 부울 또는 및 및 사용할 수 있으며 사용할 수 있습니다 | 그리고 또한. (bool1 + bool2) & bool3는 산출 할 때 믹싱으로 도망 갈 수 없습니다. false 세 변수가 모두 인 경우 true. ((1 + 1) & 1은 2 & 1이며, 이는 0 또는 false입니다.)

기억 | 그리고 || 여기에서도 동일하게 작동하지 마십시오. | 양쪽을 평가 한 다음 BitWise 또는를 평가합니다. || 첫 번째 피연산자를 평가하면 False 인 경우에만 두 번째를 평가합니다.

나는 여기서 문체 문제에 대해 논의하지 않을 것이지만, 내가 그런 일을했다면 사람들이 내가하고있는 일과 그 이유를 알도록 댓글을달라고 확신 할 것입니다.

다른 팁

표준은 다음과 같습니다.

4.5-4 "통합 프로모션"

유형 BOOL의 rvalue는 int 유형의 rvalue로 변환 될 수 있으며, 거짓은 0이되고 진실은 하나가됩니다.

5.17-7 "과제 연산자"

E1 OP = E2 형태의 표현의 거동은 E1이 한 번만 평가된다는 점을 제외하고 E1 = E1 OP E2와 동일합니다. in += 및 -=, e1은 산술 유형을 가지거나 CVQUALIFIED 완전히 정의 된 객체 유형에 대한 포인터 여야합니다. 다른 모든 경우에, E1에는 산술 유형이 있어야합니다.

4.12-1 "부울 전환"

산술, 열거, 포인터 또는 멤 0 값, NULL 포인터 값 또는 NULL 멤버 포인터 값은 False로 변환됩니다. 다른 값은 True로 변환됩니다.

그래서 이것은 그것을 의미합니다

b1 += b2

B1과 B2가 부울 인 경우

b1 = b1 + b2

그리고 B1과 B2는 0/1 정수로 홍보 된 다음 0 이외의 다른 것이 사실이라는 규칙에 따라 부울로 다시 변환됩니다.

진실 테이블은입니다

            true   false
true     true   true
false    true   false

따라서 += 실제로 표준에 따라 || =로 작동합니다. 그러나 이것은 아마도 다른 프로그래머를 혼란스럽게 할 것이므로 여전히 피할 것입니다.

3 원 운영자 만 사용할 수 있습니까?

old_value = !old_value ? possible_new_value : old_value;

사용하지 마십시오 |= 그리고 &= 부울과 함께. 그들은 대부분 일할 수 있지만 여전히 틀립니다. 일반적으로 부울 유형은 영광스러운 int 또는 char입니다. 내가 함께 일한 오래된 코드에서 Bool은 int 또는 char에 대한 typedef'd입니다. 이 경우 비트가 어떻게 든 조작 된 경우 (예 : 1&2 0 (false)). 그리고 나는 확실하지 않지만, Bitwise Operators의 결과는 Bools에게도 INT가 될 것이라고 생각합니다.

if (!old_value)
    old_value = possible_new_value;

이것은 원래 조건과 직접적으로 동일합니다. 항상 할당되지 않기 때문에 더 간단한 코드를 생성 할 수 있습니다. old_value - 그러나 나는 큰 프로그램에서 성능 차이가 쉽게 측정 할 수있을 것으로 기대하지 않을 것입니다.

한 가지 차이점은 다음과 같은 논리 연산자입니다 || 평가 순서를 보장하고 비트 와이즈 및 산술 연산자가없는 곳에서 단락을 제공합니다.

컴파일러는 부울을 숫자 값 (0, 1)으로 변환하여 연산자를 적용하고 뒤로 변환하여 비-로그 연산자를 처리 할 것이라고 생각합니다. 이러한 변환은 표준에 의해 엄격하게 정의됩니다.

산술, 열거, 포인터 또는 멤 0 값, NULL 포인터 값 또는 NULL 멤버 포인터 값은 False로 변환됩니다. 다른 값은 True로 변환됩니다.

끔찍한 매크로 해커 :

#define UPDATE(x) x = x

UPDATE(old_value) || possible_new_value;

그러나 나는 이것을 전혀 추천하지 않습니다. 이와 같은 매크로는 몇 가지 이유로 매우 나쁜 생각입니다.

보다 제정신 기능이지만 단락없이 :

bool set_or(bool &old, bool value) {
  return (old = old || value);
}

...

bool v = false;
set_or(v, true);

표준은 진실과 거짓을 명시 적으로 1과 0으로 정의한다고 생각하므로 비트 연산자를 안전하게 사용할 수 있습니다. bool 가치. 다른 맥락에서 암시 적으로 부울로 취급 될 수있는 다른 유형은 이것을 안정적으로 작동하도록 명시 적으로 변환되어야합니다.

Microsoft의 컴파일러가 INT 결과를 BOOL로 다시 변환하는 데 위험이 있다고 생각하기 때문에 Microsoft의 컴파일러 가이 작업을 수행 할 때마다 추악한 경고를 생성하는 것을 보았습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top