C++ - C++20 Designated initializers

출처
Designated initializers(지시 붙은 초기화) C++20 에서 집성체 초기화 때에 데이터 멤버를 지정하는 구문이다.

struct(class)

struct A
{
    int x = 0;
    int y = 0;
    int z = 0;
};

A a{.x = 1, .y = 2, .z = 3};
// 지정이 없는 멤버는 기본 생성자가 불린다
A b{.y = 2,}; 
// 순서가 선언 순서와 다르면 컴파일 에러(C 언어는 OK)
// A c{.y = 2, .x = 1, .z = 3};

union

공용체에서도 사용 가능하다. 단 하나만 지정한다.

union B
{
    int i;
    float f; 
};

B a{.i = 1};
// 복수 지정하면 컴파일 에러
// B b{.i = 1, .f = 1.0f};

네이스트된 지시 있는 초기화

struct A
{
    int x = 0;
    int y = 0;
    int z = 0;
};

struct B
{
    A a;
};

B a{ .a{.x=1, .y = 2, .z= 3} };

// 컴파일 에러 (C 언어라면 OK)
// B b{ .a.x = 1 };

생성자 정의 시에 대해서

생성자가 정의되어 있는 경우는 지시가 있는 초기화는 사용할 수 없다.
이 경우의 동작에 대해서는 미 정의이다.
gcc는 생성자가 호출 되었다.
clang은 컴파일 에러가 되었다.

struct A
{
    int x = 0;
    int y = 0;
    int z = 0;

    A(int,int,int):
      x(3),
      y(3),
      z(4)
    {}
};

// 에러 ???
// A a{.x=1, .y = 2, .z= 3}; 

지시 붙은 초기화의 장점

  1. 멤버 변수명이 지정 되어 있으므로 구조체의 정의를 보지 않아도 알 수 있다.
    // 각각의 값이 어떤 멤버인지 알 수 없다
    A a{1, 2, 3}; 
    // 알기 쉽다
    A a{.x=1, .y=2, .z=3}; 
    
  2. 멤버 변수 선언 순서를 틀리게 하면 컴파일 에러로 알 수 있다.
struct A
{
    int x = 0;
-   int y = 0;
    int z = 0;
+   int y = 0;
};

// y=2가 들어갈 생각인데 3이 들어갔다
A a{1, 2, 3}; // OK

// 지시 붙은 초기화 라면 선언 순서가 틀리면 컴파일 에러가 나와서 실수를 바로 알 수 있다
A a{.x=1, .y=2, .z=3}; // Error 

이 글은 2021-01-20에 작성되었습니다.