C++에 비단락 논리 "and"가 있나요?
-
20-09-2019 - |
문제
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(); }
스핀을 위해 가져 가십시오 ;-).