02. C++_Initializer_list
Initalizer_list는 c++11 표준 라이브러리에서 제공하는 타입으로, 배열의 초기화를 쉽게 처리하기위한 reference 객체입니다. 이 객체는 const T 타입의 요소로 이루어진 배열에 대한 접근을 제공하며, 중괄호 '{}'안에 나열된 값을 가져와 메모리를 초기화 합니다. 이때 배열이 놓인 메모리가 어느 위치인지는 정의되어있지 않고, readonly로 읽기 전용 메모리에 할당되어 s가 파괴될 때 같이 헤제됩니다.
std::initializer_list는 멤버함수로 size(), begin(), end() 등을 가지며, 포인터 2개로 구현되어 연속된 메모리의 시작위치와 끝 위치를 가리킵니다.
* initializer_list의 멤버함수
#include <print>
#include <initializer_list>
int main()
{
std::initializer_list<int> s = {1,2,3,4,5};
// int* first = s.begin(); //error
const int* first = s.begin();
const int* end = s.end();
size_t size = s.size();
for (auto e : s){
std::println("{}", e);
}
}
initializer_list<T>는 함수의 인자로 많이 사용되는데 일반 배열을 사용하는 것과 몇가지 차이점이 있습니다. initializer_list를 사용하면 배열의 크기를 명시적으로 지정할 필요가 없이 컴파일러가 초기화 목록의 길이를 자동으로 결정합니다. 또한 함수에 여러 값을 전달할 수 있기 때문에 함수를 호출할 때 가독성과 편의성을 높여주고, 가변 인자 함수와 같은 용도로도 사용될 수 있습니다.
#include <print>
#include <initializer_list>
void f1(int* p) {}
void f2( std::initializer_list<int> s ) {}
int main()
{
int x[5] = {1,2,3,4,5};
f1(x);
// f1({1,2,3}); error
std::initializer_list<int> s = {1,2,3,4,5};
f2(s);
f2({1,2,3});
// f2(x); error 일반 배열은 initializer_list 형태로 인자를 전달할 수 없다.
}
c++ 11부터는 객체를 초기화할 때 소괄호() 대신 중괄호{}를 사용할 수 있습니다. initializer_list는 생성자의 인자로 특히 많이 사용되는데, {}초기화를 사용하면 initializer_list를 인자로 받는 생성자가 우선적으로 호출되어 객체를 배열처럼 초기화할 수 있게 해줍니다. 이러한 특성을 활용하여 c++11부터는 std::vector, std::map, std::set 등의 stl container를 배열처럼 초기화할 수 있게 되었습니다.
#include <print>
class Object
{
public:
Object() {std::println("zero augment");} //1번
Object(int, int) {std::println("two augment");} //2번
Object(std::initializer_list<int>) {std::println("initializer list");} //3번
};
int main()
{
Object o1; //1번 생성자
Object o2(1,2); //2번 생성자
Object o3({1,2}); //3번 생성자
Object o4{1,2}; //3번 생성자
// Object o5(1,2,3); //error
Object o6{1,2,3}; //ok 3번 생성자
Object o7{1,3,3}; //ok 3번 생성자
}
//Object o3{1,2}
//1. Object(std::initializer_list) 우선적 호출
//2. 1.이 없다면 Object(int,int) 호출
int main()
{
std::vector<int> v1{1,2,3};
std::vector<int> v2 = {1,2,3};
//c++17부터 template type 인자도 생략 가능
std::vector v3{1,2,3};
std::vector v4 = {1,2,3};
}
위 예제는 강성민 강사님의 cpp intermediate 강좌의 내용을 인용하였습니다.
Course Status – ecourse 온라인 강의
initializer_list 문법 정의는 cppreference에서 확인하실 수 있습니다.