문제

tl;dr:C++에 비단락 논리 AND(&&와 유사)가 있습니까?

호출하려는 함수가 2개 있고 반환 값을 사용하여 세 번째 복합 함수의 반환 값을 알아냅니다.문제는 항상 두 함수를 모두 평가하기를 원한다는 것입니다(시스템 상태에 대한 로그 정보를 출력하므로).

즉:

bool Func1(int x, int y){
  if( x > y){
    cout << "ERROR- X > Y" << endl;
  }
}
bool Func2(int z, int q){
  if( q * 3 < z){
    cout << "ERROR- Q < Z/3" << endl;
  }
}
bool Func3(int x, int y, int z, int q){
  return ( Func1(x, y) && Func2(z, q) );
}

물론, 함수에서 조건문은 그다지 간단하지 않습니다. 그렇습니다. 임시 변수를 사용하여 두 함수의 반환값을 저장한 다음 임시 변수에 대해 "단락" 논리를 수행할 수 있다는 것을 알고 있습니다. Func3에서 한 줄 반환을 유지하면서 두 기능 모두에서 로깅 메시지를 받는 "우아한" 언어 솔루션이 있는지 궁금합니다.


답변 요약:

"Bitwise"연산자 | 그리고 & &는 효과를 얻는 데 사용될 수 있지만 반환 유형이 bool 인 경우에만 효과를 얻을 수 있습니다.ANSI C++ 사양에서 이에 대한 언급을 찾지 못했습니다.내가 알 수 있듯이 이것은 "bool"이 int(true = 1, false = 0)로 변환된 다음 비트 연산자가 사용된 다음 다시 bool로 변환되기 때문에 작동합니다.

운영자 "+" 그리고 "*"도 사용할 수 있습니다.이는 ANSI C++ 사양에 언급되어 있지 않지만 아마도 위와 같은 이유로 작동할 것입니다."+" "or"는 true가 1로 변환되고 0이 아닌 모든 값이 다시 true로 변환되기 때문에 제공됩니다."*"는 "and"에 대해 작동합니다. 왜냐하면 1(true) * 0(false) == 0(false) 및 1(true) * 1(true) == 1(true)이기 때문입니다.

이 두 가지 모두 암시적으로 유형을 정수로 변환한 다음 다시 bool로 변환하는 것 같습니다.이 두 가지 모두 코드를 유지하려는 사람을 엉망으로 만들 가능성이 높습니다.

다른 응답은 질문이 아닌 "그냥 임시 사용" 또는 "직접 구현"으로 귀결됩니다.목표는 이를 수행하기 위해 C++ 표준에 이미 구현된 연산자가 있는지 확인하는 것이었습니다.

도움이 되었습니까?

해결책

그만큼 & 연산자는 논리적 "및"작동을 수행합니다 bool 피연산자이며 짧은 회로가 아닙니다.

시퀀스 지점이 아닙니다. 피연산자 평가 순서에 의존 할 수는 없습니다. 그러나 두 피연산자가 모두 평가되었음을 보장합니다.

그래요 ~ 아니다 이것을하는 것이 좋습니다. 임시 변수를 사용하는 것이 더 나은 솔루션입니다. "영리한 코드"에 대한 가독성을 희생하지 마십시오.

다른 팁

그리고 그렇습니다. 임시 변수를 사용하여 두 함수의 반환값을 저장한 다음 임시 변수에 대해 "단락" 논리를 수행할 수 있다는 것을 알고 있습니다. 하지만 이를 유지하기 위한 "우아한" 언어 솔루션이 있는지 궁금합니다. 두 함수 모두에서 로깅 메시지를 계속 가져오는 동안 Func3에서 한 줄 반환.

그것은 "우아한"솔루션이 될 것입니다 :).에 의존 부작용 평가 순서는 우아하고 오류가 발생하기 쉬우며 프로젝트를 시작하는 다음 개발자가 이해하기 어렵습니다.에 의존 부작용 물론 평가 순서에만 의존하는 완전히 논리적이고 유효한 사용 사례인 다음 스니펫과 대조됩니다.

if ( obj != NULL && obj->foo == blah ) { /* do stuff */ }

예,이 작업을 수행하기 위해 운영자가 내장되어 있습니다.+ 단락이 아닌 회로 또는 및 * 그리고.

#include <iostream>
using namespace std;

void print(bool b)
{
    cout << boolalpha << b << endl;
}

int main() 
{
    print(true + false);
    print(true * false);
}

산출:

진실

거짓

당신은 사소하게 자신의 것을 쓸 수 있습니다.

bool LongCircuitAnd( bool term1, bool term2 ) { return term1 && term2; }

bool Func3(int x, int y, int z, int q){
  return LongCircuitAnd( Func1(x,y), Func2(z,q) ); 

그리고 당신이 매우 화려하고 싶다면, 당신은 그것을 인라인 할 수도 있습니다 !!!

좋아, 좋아, 만약 당신이 정말로 당신이 정말로 기능을 호출하는 끔찍한 오버 헤드를 원하지 않는다면.

bool Func3(int x, int y, int z, int q){
  return ((int)Func1(x,y)) * ((int)Func2(z,q)); 

그러나 나는 그것을 우아하게 생각하지 않습니다. 지나치게 똑똑한 컴파일러가 이것을 단락시킬 수 있다는 것은 생각할 수 있습니다 ...

임시 변수를 사용하려고하지만 단일 명세서로 돌아 오면 쉼표 연산자를 사용할 수 있습니다.

return (b1=Func1()), (b2=Func2()), (b1&&b2);

쉼표 연산자는 시퀀스 지점을 강제하므로 각각은 왼쪽 피연산자를 평가하고 결과를 버린 다음 오른쪽 피연산자를 평가합니다.

또 다른 가능성이 있지만, 내가 추천하는 경향이있는 것은 두 기능이 '&&'연산자에 과부하가 걸리는 유형을 반환하는 것입니다. 오버로드 된 연산자가 함수를 호출하므로 항상 평가합니다. 둘 다 내장 운영자가하지 않는 경우 (&&와 같은)에서도 피연산자는 일반적으로 문제가되지만이 경우에는 정확히 원하는 것입니다.

class mybool { 
    bool value;
public:
    bool operator&&(mybool const &other) const { 
        return value && other.value;
    }
};

mybool Func1(int, int);
mybool Func2(int, int);

bool Func3(int x, int y, int z, int q) { 
    return Func1(x, y) && Func2(z,q);
}

이것이 효과가 있지만, 그것은 너무 "영리한"것인 것처럼 보입니다. 대부분의 독자들에게는 전혀 분명하지 않을 것입니다. 다른 이름 mybool 도움이 될 수 있지만, 오프 핸드 나는 의도를 잘 반영하는 것을 생각할 수 없다.

예. 과부하 된 버전 operator&& 그리고 operator|| 단락하지 마십시오-왼쪽 피연산자가 결과를 "결정"하더라도 두 피연산자를 평가합니다 ... (원천)

즉, 과부하하지 마십시오 operator&& 또는 operator||. 살펴볼 유지 보수 프로그래머에게 친절하십시오. && 또는 || 그리고 그들이 단락이라고 가정합니다.

거의 보편적이지만 종종 문서화되지 않은 비표준 운영자가 소개되었습니다 정확히이 목적을 위해 GCC가 함께 개척했습니다 x ?: y (x 0이 아닌 경우 x), 이제 슬프게도 제거되었습니다. >? 그리고 <? 최소/최대 운영자 및 복합 할당 양식 (참조 http://gcc.gnu.org/onlinedocs/gcc/deprecated-features.html). 슬프게도 & 그리고 && 이미 사용중인 그들은 적절한 캐릭터 시퀀스를 찾기 위해 배럴의 바닥을 긁어 낸 것 같습니다. 그러나 그것은 단지 내 의견 일뿐입니다. 이것이 왜 이것이 선택되었는지에 대한 역사적 설명을 환영합니다.

따라서 현재 다른 많은 운영자만큼 잘 알려져 있지는 않지만 그만큼 >! 운영자 (적절하지만 지루하게도 "긴 회로 및"라고 불리며, 대부분의 C 및 C ++ 컴파일러 (GCC 및 MSVC ++ 포함)에 의해 추가로 "긴 회로 및", 그러나 구어 적으로 "더 큰 매듭"이 추가되었습니다.

bool f1() { ... }
bool f2() { ... }

...
bool f3() { return f1() >! f2(); }

스핀을 위해 가져 가십시오 ;-).

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