이것이 삼항 연산자를 합리적으로 사용하는 것입니까?[닫은]

StackOverflow https://stackoverflow.com/questions/522919

  •  22-08-2019
  •  | 
  •  

문제

다음과 같은 코드로 인해 발생하는 이해/유지 관리 문제가 있습니까?

inVar1 == 0 ? NULL : v.push_back(inVar1);
inVar2 == 0 ? NULL : v.push_back(inVar2);

기타 등등.

아마도 혼란스러운 아이디어는 일반적인 설명인 변수 할당 대신 프로그램 흐름을 위해 삼항 연산자를 사용하는 것입니다.

직장에서 이 사용법을 다루는 코딩 표준을 본 적이 없으므로 이 작업을 수행하는 것이 편안하지만 그렇게 하지 않을 타당한 이유가 있는지 알고 싶습니다.

도움이 되었습니까?

해결책

나는 단순히 입력하는 것보다 혼란스럽고 읽기가 훨씬 어렵다고 생각합니다.

if (inVar != 0)
  v.push_back(inVar);

나는 당신의 예제를 여러 번 스캔하여 결과가 확실하게 무엇인지 알아 내야했습니다. 나는 심지어 당신의 예보다 단일 라인 if () {} 문을 선호합니다. 그리고 나는 단일 라인 if 문을 싫어합니다 :)

다른 팁

3 원 운영자는 값을 반환하기위한 것입니다.

IMO, 상태를 돌연변이해서는 안되며 반환 값을 사용해야합니다.

다른 경우에는 IF 문을 사용하십시오. 진술이 코드 블록을 실행하기위한 경우.

3 차는 좋은 일이며, 나는 일반적으로 사용을 홍보합니다.

당신이 여기서하고있는 일은 신뢰성을 손상시킵니다. 예, 더 짧지 만 불필요하게 복잡합니다.

나는 이것이 피해야한다고 생각한다. 대신 1 라인 IF 문을 사용할 수 있습니다.

if(inVar1 != 0) v.push_back(inVar1);

요즘 컴파일러는 3 원 운영자만큼 빠른 IF가됩니다.

다른 소프트웨어 개발자가 읽는 것이 얼마나 쉬운 지 목표입니다.

나는 투표한다

if ( inVar != 0 )
{
   v.push_back( inVar );
}

왜 괄호가 ... 당신은 언젠가 당신이 거기에 다른 것을 넣고 싶을 수도 있고 괄호는 당신에게 미리 준비되어 있기 때문입니다. 요즘 대부분의 편집자들은 어쨌든 그것들을 넣을 것입니다.

Ternary Operator를 사용하면 아무것도 얻지 못하고 코드 가독성을 상하게합니다.

Ternary 연산자는 사용하지 않는 값을 반환하기 때문에 홀수 코드입니다. An의 사용 if 당신과 같은 경우에는 훨씬 더 분명합니다.

Litb는 의견에서 언급했듯이 유효한 C ++가 아닙니다. 예를 들어 GCC는이 코드에서 오류가 발생합니다.

error: `(&v)->std::vector<_Tp, _Alloc>::push_back [with _Tp = int, _Alloc =
std::allocator<int>](((const int&)((const int*)(&inVar1))))' has type `void' 
and is not a throw-expression

그러나 캐스팅을 통해 주변을 둘러 볼 수 있습니다.

inVar1 == 0 ? (void)0 : v.push_back(inVar1);
inVar2 == 0 ? (void)0 : v.push_back(inVar2);

그러나 어떤 비용으로? 그리고 어떤 목적을 위해?

이 상황에서 IF 진술보다 더 간결한 것이 아닙니다.

inVar1 == 0 ? NULL : v.push_back(inVar1);
if(inVar1 != 0) v.push_back(inVar1);

실제로, 나는 이런 유형의 글을 낙담시키는 사람들의 감정에 동의하지만 (읽을 때, 당신은 부작용에 대한 표현을 스캔하기 위해 추가 작업을해야한다), 나는 제안하고 싶습니다.

!inVar1 ?: v.push_back(inVar1);
!inVar2 ?: v.push_back(inVar2);

... 당신이 모호하게하려고한다면, 그것은입니다. GCC가 허용됩니다 x ?: y 대신에 x ? x : y. :-)

조건부 인수를 사용하여 일부 함수를 호출해야 할 때 삼항 연산자를 사용합니다. 이 경우에는 더 좋습니다. if.

비교하다:

printf("%s while executing SQL: %s",
        is_sql_err() ? "Error" : "Warning", sql_msg());

~와 함께

if (is_sql_err())
    printf("Error while executing SQL: %s", sql_msg());
else
    printf("Warning while executing SQL: %s", sql_msg());

나는 전자가 더 매력적이라고 ​​생각한다.그리고 그것은 준수합니다 마른 원칙적으로 후자와는 달리 거의 동일한 두 줄을 작성할 필요가 없습니다.

나는 당신이 올바른 if 구조를 수행하는 데 더 나은 서비스를받을 것이라고 생각합니다. 나는 심지어 IF 구조와 항상 버팀대를 갖는 것을 선호합니다.이 경우 조건부 실행에 나중에 선을 추가해야합니다.

if (inVar != 0) {
    v.push_back(inVar);
}

나는 때때로 제 3 원이 생성자의 초기화 목록에서 필요한 악이라고 생각합니다. 나는 주로 메모리를 할당하려는 생성자에 사용하고 생성자의 본문 앞에 포인터를 설정할 포인터를 설정합니다.

예를 들어, 벡터를 입력으로 가져 가고 싶었던 정수 스토리지 클래스가 있었지만 내부 표현은 배열입니다.

class foo
{
public:
    foo(std::vector<int> input);
private:
    int* array;
    unsigned int size;
};

foo:foo(std::vector<int> input):size(input.size()), array( (input.size()==0)?
        NULL : new int[input.size])
{
    //code to copy elements and do other start up goes here
}

이것이 제가 3 원 운영자를 사용하는 방법입니다. 나는 그것이 어떤 사람들처럼 혼란 스럽다고 생각하지 않지만 나는 그들이 얼마나 많이 사용하는지 제한해야한다고 생각합니다.

고문당한 삼여물의 대부분은 (이를위한 방법은 무엇입니까?) 나는 단지 IF 진술이 속하지 않거나 갈 수없는 장소에서 IF 진술에 실제로 속한 논리를 넣는 시도 일뿐입니다.

예를 들어:

if (inVar1 != 0)
  v.push_back(inVar1);
if (inVar2 != 0)
  v.push_back(inVar2);

v.push_back이 무효라고 가정하지만 다른 기능으로 전달 해야하는 값을 반환하면 어떻게해야합니까? 이 경우 : 다음과 같은 것을보아야합니다.

SomeType st;
if (inVar1 != 0)
  st = v.push_back(inVar1);
else if (inVar2 != 0)
  st = v.push_back(inVar2);
SomeFunc(st);

그러나 그것은 그런 간단한 코드에 대해 소화하는 것이 더 중요합니다. 내 해결책 : 다른 기능을 정의합니다.

SomeType GetST(V v, int inVar1, int inVar2){
    if (inVar1 != 0)
      return v.push_back(inVar1);
    if (inVar2 != 0)
      return v.push_back(inVar2);        
}

//elsewhere
SomeFunc(GetST(V v, inVar1, inVar2));

어쨌든 요점은 이것입니다. 만약 당신이 3 원을 위해 너무 고문을받은 논리가 있다면 if 문에 넣으면 코드를 혼란스럽게 할 것입니다. 다른 곳에 두십시오!

inVar1 != 0 || v.push_back(inVar1);
inVar2 != 0 || v.push_back(inVar2);

Perl과 같은 언어에서 발견되는 일반적인 패턴.

테나리 인수 중 하나 또는 둘 다에 여러 메소드 호출이있는 경우 잘못되었습니다. 어떤 진술이 짧고 단순 해야하는지에 관계없이 모든 코드 라인. 이상적으로는 복합적이지 않습니다.

다른 사람들이 언급했듯이 적절한 if 진술은 더 읽을 수 있습니다. 또한 디버거를 사용하여 코드를 밟을 때 모든 것이 한 줄에 있거나 삼상 표현을 사용하는 경우 IF의 지점을 쉽게 알 수 없습니다.

if (cond) doIt();

cond ? noop() : doIt();

반면 다음은 단계를 밟는 것이 훨씬 좋습니다 (버팀대가 있든 없든) :

if (cond) {
    doIt();
}

언급했듯이 1 라인 IF 문보다 짧거나 명확하지 않습니다. 그러나 그것은 또한 더 이상은 아니며 실제로 그만큼 어렵지 않습니다. 3 원 운영자를 알고 있다면 무슨 일이 일어나고 있는지 분명합니다.

결국, 나는 변수에 할당 된 경우 (상태도 돌연변이 상태이더라도) 아무도 문제가 없을 것이라고 생각합니다.

var2 = inVar1 == 0 ? NULL : v.push_back(inVar1);

3 차 연산자가 항상 값을 반환한다는 사실은 IMO-와 관련이 없습니다. 모든 반환 값을 사용해야 할 필요성은 없습니다. 결국, 할당은 값을 반환합니다.

즉, 널 지점으로 가로 질러 달렸다면 IF 문으로 대체 할 것입니다.

하지만, 3 줄 if 문을 대체 한 경우 :

if (inVar == 0) {
   v.doThingOne(1);
} else {
   v.doThingTwo(2);
}

와 함께:

invar1 == 0 ? v.doThingOne(1) : v.doThingTwo(2);

~할 것 같다 내 기분에 따라 남겨주세요. ;)

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