1. 개요
오늘은 초기화자 리스트(Initializer_list)에 대해서 공부하도록 하겠습니다.
2. 초기화자 리스트란?
초기화자 리스트란 중괄호를 사용해서 배열 및 벡터를 초기화할때 많이 사용하는 방식입니다.
int arr[] = {1, 2, 3, 4};
이러한 코드를 많이 보셨을거라 판단됩니다.
그렇다면 아래의 코드는 과연 가능할까요?
vector<int> v = {1, 2, 3, 4};
물론 가능합니다.
C++11부터 사용자에게도 이러한 문법을 사용할수 있도록 하게 하였습니다.
#include <iostream>
class A
{
public:
A(std::initializer_list<int> l)
{
for (auto itr = l.begin(); itr != l.end(); ++itr)
{
std::cout << *itr << std::endl;
}
}
};
int main()
{
A a = { 1, 2, 3, 4, 5 };
}
컴파일을 완료가 되었다면
이러한 결과값을 확인할수 있습니다.
초기화자 리스트는 우리가 {} 를 이용해서 생성자를 호출할 때, 클래스의 생성자들 중에 initialize_list를 인자로 받는 생성자가 있다면 전달됩니다.
2. 주의점
생성자들 중에서 initializer_list 를 받는 생성자가 있다면 한 가지 주의해야할 점이 있습니다.
만일{}를 이용해서 객체를 생성할 경우 생성자 오버로딩 시에 해당 함수가 최우선 으로 고려된다는 점입니다.
예를 들어서 vector 의 경우 아래의 같은 형태의 생성자가 존재합니다.
vector(size_type count);
이 생성자는 count 개수 만큼의 원소 자리를 미리 생성해놓습니다(size를 생성함)
vector v{10};
이러면 어떻게 될까요? 생성자를 호출하나요? 아닙니다. 그냥 원소 1개 짜리 initializer_list 라고 생각해서 10을 보관하고 있는 벡터를 생성하게 됩니다.
따라서, 이러한 불상사를 막기 위해서는 {}로 생성하기 보다는 ()를 이용해서
vector v(10);
과 같이 v 를 생성한다면 우리가 원하는 생성자를 호출할 수 있게 됩니다.
initializer_list 를 받는 생성자가 최우선적으로 고려된다는 말은, 컴파일러가 최선을 다해서 해당 생성자와 매칭시키려고 노력한다는 의미와 같고, 예를 들어서 아래와 같은 코드를 살펴보면
#include <iostream>
class A
{
public:
A(int x, double y)
{
std::cout << "일반 생성자! " << std::endl;
}
A(std::initializer_list<int> lst)
{
std::cout << "초기화자 사용 생성자! " << std::endl;
}
};
int main() {
A a(3, 1.5); // Good
A b{ 3, 1.5 }; // Bad!
}
오류가 생깁니다.
앞서 설명에는 {}는 데이터 손실이 있는 변환을 할 수 없다고 말했습니다. 그럼 string은 가능할까요?
https://chogyujin-study.tistory.com/118
#include <initializer_list>
#include <iostream>
#include <string>
class A
{
public:
A(int x, double y)
{
std::cout << "일반 생성자! " << std::endl;
}
A(std::initializer_list<std::string> lst)
{
std::cout << "초기화자 사용 생성자! " << std::endl;
}
};
int main()
{
A a(3, 1.5); // 일반
A b{ 3, 1.5 }; // 일반
A c{ "abc", "def" }; // 초기화자
}
가능은 합니다 int 나 doulbe이 string으로 변환될 수 없기 때문에 initializer_list를 받는 생성자는 아예 고려 대상에서 제외됩니다.
3. Ref
'개발자 면접 공부 > C-C++' 카테고리의 다른 글
NULL 포인터로 객체의 함수가 왜 호출되냐? (0) | 2024.03.26 |
---|---|
VTable 위치 파악 (0) | 2024.03.25 |
유니폼 초기화 (0) | 2024.03.06 |
C++ vs C# (1) | 2024.02.18 |
Move Semantics (0) | 2023.10.29 |