프로그래밍을 하다 보면 함수가 반환한 값을 확인하고, 그 값에 따라 조건부로 다른 동작을 수행해야 하는 경우가 매우 흔합니다. 전통적인 방식으로는 아래와 같이 코드를 작성하게 됩니다.
// 어떤 메서드 또는 함수
return_type foo(Params);
// Params로 함수를 호출하고
// 반환값을 var1에 저장
auto var1 = foo(Params);
if (var1 == /* some value */) {
// 무언가 수행
} else {
// 다른 작업 수행
}일반적인 if-else 구조
일반적인 조건문 블록은 크게 두 부분으로 구성됩니다. 먼저 변수를 설정하는 선택적인 초기화 문장(init-statement)이 존재하고, 그 뒤에 if-else 블록이 따라옵니다.
init-statement
if (condition) {
// 무언가 수행
} else {
// 다른 작업 수행
}C++17에서 달라진 점
C++17부터는 이 초기화 문장을 '이니셜라이저(initializer)'라고 부르며, if-else 블록 안에 직접 넣을 수 있게 되었습니다.
if (init-statement; condition) {
// 무언가 수행
} else {
// 다른 작업 수행
}변수 스코프의 제한
이 기능의 핵심 장점은 조건 변수의 유효 범위(scope)가 해당 if-else 블록 내부로 한정된다는 점입니다. 덕분에 서로 다른 조건문 블록에서 같은 이름의 식별자를 자유롭게 재사용할 수 있습니다.
if (auto var1 = foo(); condition) {
...
}
else{
...
}
// 또 다른 if-else 블록
// 같은 이름 var1 재사용 가능
if (auto var1 = bar(); condition) {
....
}
else {
....
}switch 문에서의 활용
마찬가지로 switch 문도 업데이트되어, switch 괄호 안에 초기화 표현식을 직접 넣을 수 있게 되었습니다. 초기화 문장 뒤에는 어떤 변수를 대상으로 각 case를 검사할지 반드시 지정해야 합니다.
switch (initial-statement; variable) {
....
// cases
}전체 예제 프로그램
아래는 C++17에서 새롭게 도입된 초기화문이 포함된 if-else 기능을 설명하는 완전한 프로그램입니다.
// C++17에서 도입된 init if-else 기능을
// 설명하기 위한 프로그램
#include <iostream>
#include <cstdlib>
using namespace std;
int main() {
// 프로그램 후반부에서 사용할
// rand 함수 설정
srand(time(NULL));
// C++17 이전 방식
int I = 2;
if ( I % 2 == 0)
cout << I << " is even number" << endl;
// C++17 이후 방식
// if(init-statement; condition)
if (int I = 4; I % 2 == 0 )
cout<< I << " is even number" << endl;
// switch 문
// switch(init;variable)
switch (int I = rand() % 100; I) {
default:
cout<< "I = " << I << endl; break;
}
}이처럼 C++17의 초기화문 기능을 활용하면 변수 선언과 조건 검사를 한 문장으로 결합해 코드를 더욱 간결하게 만들 수 있고, 변수의 유효 범위를 최소화하여 의도치 않은 충돌이나 버그 발생 가능성도 크게 줄일 수 있습니다.