게임 개발/C++

[C++] 중괄호 초기화 - 2. initializer_list

유행성바코드 2025. 3. 20. 20:18

중괄호 초기화 - 2. initializer_list

목차

  • 01. Intro
  • 02. initializer_list
    • initializer_list란?
    • 클래스 생성자에서 활용
    • explicit 키워드와 활용
    • 주의점
  • 03. 마무리
  • 04. 연관 내용

01. Intro

오늘은 중괄호 초기화에서 사용하는 [initializer_list]에 대해 알아보겠습니다.

 


02. initializer_list

initializer_list란?

initializer_list는 vector와 같은 container에서 중괄호 초기화를 지원하는 생성자입니다.

 

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	// 중괄호 초기화
	vector<int> vec{ 1,2,3 };

	for (const int& each : vec)
	{
		cout << each << endl;
	}

	return 0;
}

위 코드는 vector에서 중괄호 초기화를 사용하는 예시입니다.

 

클래스 생성자에서 활용

vector와 같은 container뿐만 아니라, 우리가 직접 만든 클래스에서도 활용할 수 있습니다.

즉, 클래스에 initializer_list를 이용한 생성자를 선언하면, 중괄호를 이용한 초기화를 할 수 있습니다.

 

#include <iostream>
#include <vector>

using namespace std;

class Sport
{
public:
	
    // initializer_list 생성자
	Sport(initializer_list<int> il) : vec(il) {}

	vector<int> vec;
};

int main()
{
	Sport sport{ 1, 2, 3 };

	for (const int& each : sport.vec)
	{
		cout << each << endl;
	}

	return 0;
}

 

initializer_list 생성자를 선언해서, 클래스 멤버 변수의 vector<int>에 바로 대입할 수 있습니다.

이처럼 initializer_list를 활용하면, 직관적인 초기화가 가능합니다.

 

explicit 키워드와 활용

 

또한, explicit와 함께 활용하면, 암시적인 변환을 방지할 수 있습니다.

암시적 변환인 위 형태로는 초기화를 할 수 없습니다.

 

그래서, explicit 키워드와 함께 사용하면, 아래 코드처럼 초기화를 해야 합니다.

#include <iostream>
#include <vector>

using namespace std;

class Sport
{
public:

	explicit Sport(initializer_list<int> il) : vec(il) {}

	vector<int> vec;
};

int main()
{
	// Sport sport = { 1, 2, 3 };
	Sport sport{ 4, 5, 6 };

	for (const int& each : sport.vec)
	{
		cout << each << endl;
	}

	return 0;
}

sport{} 형태로 초기화를 하면, 정상적으로 작동합니다.

 

주의점

하지만, initialize_list가 항상 장점만 있는 것은 아닙니다.

이를 사용할 때, 몇 가지 주의해야 할 부분을 알아보도록 하겠습니다.

 

1. initializer_list 생성자가 다른 생성자보다 우선순위가 높음

#include <iostream>

using namespace std;

class Sport
{
public:

	Sport(int x, int y)
	{
		cout << "Sport(int, int)" << endl;
	}

	Sport(initializer_list<int> il)
	{
		cout << "initializer_list<int>" << endl;
	}
};

int main()
{
	Sport sport{ 1, 2 };

	return 0;
}

 

위 코드로 실행할 경우, 중괄호 초기화로 인해 initializer_list 생성자가 호출됩니다.

정수형 인자 2개를 받는 생성자가 있음에도 불구하고, initializer_list 생성자 우선순위가 더 높아 위와 같은 결과를 얻을 수 있습니다.

 

이를 해결하기 위해서는 객체를 생성할 때, 초기화 방식을 다르게 진행하면 됩니다.

Sport sport{ 1, 2 };
Sport sport2(3, 4);

객체를 생성할 때, ()를 이용해서 초기화를 하면, 정수형 인자 2개를 받는 생성자를 호출합니다.

이처럼 같은 정수형 인자 개수임에도, 초기화하는 형태인 (){}에 따라 다른 결과를 얻을 수 있습니다.

 

2. initializer_list로 받은 값은 수정 불가능 상태

initializer_list로 받은 값들은 const 타입이므로 오로지 읽기만 가능합니다.

그래서, 아래와 같은 코드로 작성할 경우 컴파일 에러가 발생합니다.

#include <iostream>

using namespace std;

class Sport
{
public:

	Sport(initializer_list<int> il)
	{
		cout << "initializer_list<int>" << endl;
		
        	// 에러 발생
		for (int& x : il)
		{
			x += 10;
		}
	}
};

int main()
{
	Sport sport{ 1, 2 };

	return 0;
}

위 사진에 보면, const int 타입이어서 정수형 레퍼런스로 담을 수 없다는 에러가 발생합니다.

 


03. 마무리

오늘을 끝으로 중괄호 초기화에 대한 주제를 마치도록 하겠습니다.

 


04. 연관 내용

  • [C++] 중괄호 초기화 - 1. 사용 용도
 

[C++] 중괄호 초기화 - 1. 사용 용도

중괄호 초기화 - 1. 사용 용도 목차01. Intro02. 중괄호 초기화중괄호 초기화란?장&단점사용 예시03. 마무리04. 연관 내용01. Intro오늘은 C++11에서 추가된 새로운 초기화 기법인 [중괄호 초기화]에

epidemic-barcode.tistory.com

 

 


 

읽어주셔서 감사합니다.

틀린 내용 지적은 언제나 환영입니다!

'게임 개발 > C++' 카테고리의 다른 글

[C++] 람다 함수 - 1. 기본 형태  (0) 2025.03.25
[C++] 동적 할당 - new/delete  (0) 2025.03.21
[C++] 중괄호 초기화 - 1. 사용 용도  (0) 2025.03.19
[C++] auto 키워드  (0) 2025.03.18
[C++] explicit 키워드  (0) 2025.03.17