주간 팁 #172: 지정 초기화자(Designated Initializers)

원래 TotW #172로 2019년 12월 11일 게시됨
작성자: Aaron Jacobs
2020-04-06 업데이트됨

빠른 링크: abseil.io/tips/172

지정 초기화자는 구조체의 내용을 간결하면서도 읽기 쉽고 유지보수 가능한 방식으로 지정하기 위한 C++20 표준의 문법입니다. 다음과 같은 반복적인 코드를 작성하는 대신:

CPP
struct Point {
  double x;
  double y;
  double z;
};

Point point;
point.x = 3.0;
point.y = 4.0;
point.z = 5.0;
클릭하여 더 보기

지정 초기화자를 사용하여 다음과 같이 작성할 수 있습니다:

CPP
Point point = {
    .x = 3.0,
    .y = 4.0,
    .z = 5.0,
};
클릭하여 더 보기

이 방식은 반복 작업을 줄이는 데 도움이 될 뿐만 아니라, 더 다양한 상황에서도 사용할 수 있습니다. 예를 들어, 구조체를 const로 설정하여 번거로운 우회 작업 없이도 변경 불가능하게 만들 수 있습니다:

CPP
// 코드가 복잡한 경우 이 구조체가 절대 변경되지 않음을 독자에게 명확히 알립니다.
const Point character_position = { .x = 3.0 };
클릭하여 더 보기

또는 추가 식별자를 범위 내에 도입하지 않고도 함수 호출에서 직접 사용할 수 있습니다:

CPP
std::vector<Point> points;
[...]
points.push_back(Point{.x = 3.0, .y = 3.0});
points.push_back(Point{.x = 4.0, .y = 4.0});
클릭하여 더 보기

의미론

지정 초기화자는 집합 초기화의 한 형태로, 집합에서만 사용할 수 있습니다. 이는 “사용자 정의 생성자나 가상 함수가 없는 구조체 또는 클래스"를 의미하며, 일반적으로 Google 스타일에서는 class 대신 struct를 사용할 때 해당됩니다.

C++20 지정 초기화자의 의미론은 생성자에서의 멤버 초기화 목록과 같은 다른 C++ 언어 기능을 기반으로 예상할 수 있는 동작을 합니다. 명시적으로 언급된 필드는 제공된 표현식으로 초기화되며, 기본 동작을 원할 경우 필드를 생략할 수 있습니다:

CPP
Point point = {
    .x = 1.0,
    // y는 0.0으로 설정됨
    .z = 2.0,
};
클릭하여 더 보기

위에서 “기본값"은 무엇을 의미할까요? 특별한 경우(예: union)를 제외하고, 다음과 같습니다:

이 동작은 일반적으로 가장 예상 가능한 결과를 제공합니다. 자세한 내용은 표준을 참조하세요.


역사와 언어 트리비아

지정 초기화자는 C99 이후 C 언어의 표준적인 일부였으며, 이전부터 컴파일러에서 비표준 확장으로 제공되었습니다. 하지만 최근까지는 C++의 일부가 아니었습니다. 이는 C가 C++의 부분 집합이 아니었던 주목할 만한 예입니다. 이로 인해 Google 스타일 가이드는 사용하지 말 것을 권장하기도 했습니다.

20년이 지나 상황이 바뀌었습니다. 이제 지정 초기화자는 C++20 표준의 일부가 되었습니다.

C++20의 지정 초기화자는 C 버전에 비해 몇 가지 제한이 있습니다:

라이선스

저작자: Jaehun Ryu

링크: https://jaehun.me/posts/abseil-tip-172-%EC%A7%80%EC%A0%95-%EC%B4%88%EA%B8%B0%ED%99%94%EC%9E%90designated-initializers/

라이선스: CC BY 4.0

이 저작물은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스에 따라 이용할 수 있습니다. 출처를 밝히면 상업적 목적을 포함해 자유롭게 이용 가능합니다.

댓글

검색 시작

검색어를 입력하세요

↑↓
ESC
⌘K 단축키