Programing

"if"문에서 변수 초기화

crosscheck 2020. 10. 12. 07:13
반응형

"if"문에서 변수 초기화


C ++ 17에서 if다음과 같은 명령문 에서 변수를 초기화 할 수 있다는 것을 읽었습니다.

if (int length = 2; length == 2)
    //execute something

대신에

int length = 2;
if (length == 2)
    //do something

더 짧지 만 코드 가독성에 영향을 미치며 (특히이 새로운 기능을 모르는 사람들에게) 대규모 소프트웨어 개발에 나쁜 코딩 관행이라고 생각합니다.

코드를 짧게 만드는 것 외에이 기능을 사용하면 어떤 이점이 있습니까?


그것은의 범위를 제한 length받는 사람 if혼자. 그래서 우리가 글을 쓸 수 있었을 때 우리가 원래 얻었던 것과 같은 혜택을 얻습니다.

for(int i = 0; i < ... ; ++i) {
   // ...
}

변수 누출 대신

int i;
for(i = 0; i < ... ; ++i) {
   // ...
}

몇 가지 이유로 수명이 짧은 변수가 더 좋습니다. 그러나 몇 가지를 말하면 :

  1. 수명이 짧을수록 관련없는 코드 줄을 읽을 때 명심해야 할 사항이 줄어 듭니다. i루프 또는 if외부에 존재하지 않는 경우 , 그 값을 외부에 신경 쓸 필요가 없습니다. 또한 그 값이 의도 된 범위를 벗어난 프로그램의 다른 부분과 상호 작용할 것이라고 걱정할 필요가 없습니다 ( i위가 다른 루프에서 재사용되는 경우 발생할 수 있음 ). 코드를 따르고 추론하기가 더 쉽습니다.

  2. 변수가 자원을 보유하고있는 경우 해당 자원은 이제 가능한 가장 짧은 기간 동안 보유됩니다. 그리고 이것은 불필요한 중괄호가 없습니다. 또한 자원이 if혼자 와 관련이 있음이 분명합니다 . 이것을 동기 부여의 예로 고려하십시오

    if(std::lock_guard _(mtx); guarded_thing.is_ready()) {
    }
    

동료가 기능을 인식하지 못하는 경우 가르치십시오! 배우고 싶지 않은 프로그래머를 달래는 것은 기능을 피하는 핑계가되지 않습니다.


코드를 짧게 만드는 것 외에이 기능을 사용하면 어떤 이점이 있습니까?

변수 범위를 줄입니다. 이것은 당신이 추론해야 할 식별자의 지역성을 강화하기 때문에 의미가 있고 가독성을 증가시킵니다. 명령문 내부의 긴 init 문 if은 피해야 한다는 데 동의 하지만, 짧은 내용은 괜찮습니다.

C ++ 17 이전의 결과에 대해 이미 초기화 및 분기를 수행 할 수 있습니다.

int *get(); // returns nullptr under some condition

if (int *ptr = get())
    doStuff();

이것은 개인의 의견에 따라 다르지만 명시적인 조건을 더 읽기 쉽게 고려할 수 있습니다.

if (int *ptr = get(); ptr != nullptr)
    doStuff();

게다가, 사람들이 익숙하지 않다는 사실을 언급하여 기능의 가독성에 반대하는 것은 위험합니다. 사람들은 어느 시점에서 스마트 포인터에 익숙하지 않았지만 오늘날 우리 모두는 그들이 거기에있는 것이 좋은 일이라는 데 동의합니다.


새로운 형태의 if 문은 많은 용도로 사용됩니다.

현재 이니셜 라이저는 문 앞에 선언되어 주변 범위로 유출되거나 명시 적 범위가 사용됩니다. 새로운 형식을 사용하면 이러한 코드를 더 간결하게 작성할 수 있으며 개선 된 범위 제어를 통해 오류가 발생하기 쉬운 일부 구성을 좀 더 강력하게 만들 수 있습니다.

이니셜 라이저가있는 If 문에 대한 개방형 표준 제안

여기에 이미지 설명 입력

따라서 요약하면이 문은 일반적인 코드 패턴을 단순화하고 사용자가 범위를 좁게 유지하는 데 도움이됩니다.

도움이 되었기를 바랍니다.


변수의 범위를 최소화하기 위해 생성시 유효한 경우에만 리소스를 정의하는 관용구가 있습니다 (예 : 파일 스트림 객체 ) :

if(auto file = std::ifstream("filename"))
{
    // use file here
}
else
{
    // complain about errors here
}

// The identifier `file` does not pollute the wider scope

때로는 실패를 기본 절로 만들고 유효한 리소스를 절로 만들기 위해 해당 테스트의 논리를 반대로 할 수 있기를 원합니다 else. 이전에는 불가능했습니다. 하지만 이제 우리는 할 수 있습니다 :

if(auto file = std::ifstream("filename"); !file)
{
    // complain about errors here
}
else
{
    // use file here
}

예를 들어 예외가 발생할 수 있습니다.

if(auto file = std::ifstream(filename); !file)
    throw std::runtime_error(std::strerror(errno));
else
{
    // use file here
}

어떤 사람들 은 오류 발생시 함수가 조기중단 되고 그렇지 않으면 진행 되도록 코딩하는 것을 좋아합니다 . 이 관용구는 어떤 사람들이 더 자연스럽게 생각할 수있는 연속 논리 위에 물리적으로 중단 논리를 둡니다.


논리적 이벤트에 특히 유용합니다. 이 예를 고려하십시오.

char op = '-';
if (op != '-' && op != '+' && op != '*' && op != '/') {
    std::cerr << "bad stuff\n";
}

Seems a bit rough. Unless you are very familiar with OR, AND with negations, you might need to pause and think about this logic - which is generally poor design. With the if-initialization you can add expressiveness.

char op = '-';
if (bool op_valid = (op == '-') || (op == '+') || (op == '*') || (op == '/'); !op_valid) {
    std::cerr << "bad stuff\n";
} 

the named variable can be re-used inside the if too. E.g:

if (double distance = std::sqrt(a * a + b * b); distance < 0.5){
    std::cerr << distance << " is too small\n";
}

This is great, especially given that the variable is scoped and therefore doesn't pollute the space afterwards.


This is an extension of an existing feature, which aids readability in my experience.

if (auto* ptr = get_something()) {
}

Here we both create the variable ptr and we test against it being non-null. The scope of ptr is limited to where it is valid. It is far, far easier to convince yourself that all use of ptr is valid.

But what if we are talking about something that doesn't convert to bool that way?

if (auto itr = find(bob)) {
}

작동하지 않습니다. 그러나이 새로운 기능을 통해 다음을 수행 할 수 있습니다.

if (auto itr = find(bob); itr != end()) {
}

"이 초기화가 유효 할 때"라는 절을 추가하십시오.

본질적으로 이것은 "일부 표현식을 초기화하고 유효 할 때 일부 코드를 수행합니다. 유효하지 않으면 폐기"를 의미하는 토큰 세트를 제공합니다.

C ++ 98 이후로 포인터 테스트 트릭을 수행하는 것은 관용적이었습니다. 일단 그것을 받아 들인다면,이 확장은 당연합니다.

참고 URL : https://stackoverflow.com/questions/56866458/initializing-variables-in-an-if-statement

반응형