종제로
종제로 Devlog
종제로
전체 방문자
오늘
어제
  • 분류 전체보기 (43)
    • C, C++ (22)
      • C, C++ (10)
      • Modern C++ (4)
      • 전문가를 위한 C++ (책) (8)
    • DirectX 자체엔진 개발 (8)
    • 자료구조 알고리즘 (10)
      • 공부 (9)
      • 문제풀이 (1)
    • 자기 계발 (1)
    • 기타 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • directX
  • C++
  • c++ 17
  • 자료구조
  • DirectX11
  • 알고리즘
  • 모두의C언어
  • 전문가를 위한 C++
  • c++ 11
  • C

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
종제로

종제로 Devlog

C, C++/Modern C++

[C++ 11] 중괄호 초기화, 초기화 리스트(Initialize List)

2022. 4. 21. 12:08

1. 4가지 초기화 방법

int main()
{
    int value1 = 5; 	// C
    int value2(5);  	// C++
    int value3{ 5 };	// C++ 11 유니폼 초기화(균일한 초기화)
    int value4{};   	// C++ 11 default인 0으로 초기화됨
}

 

2. 중괄호 초기화 시 주의할 점

중괄호 초기화는 축소변환(narrowing conversion)을 지원하지 않는다.

int main()
{
    // 중괄호 초기화는 축소변환(narrowing conversion)을 지원하지 않는다.
    // 즉 자동으로 변환되는 것을 막을 수 있다.

    // 컴파일 에러난다.
    int v1{ 5.1 };

    double d{ 0.5f };
    int i{ d }; // 마찬가지로 컴파일 에러, 데이터가 잘리는 것을 지원하지 않는다.
	int i(d);	// ok

    double x, y, z;
    int sum1{ x + y + z };  // error
    int sum2(x + y + z);    // ok
    int sum3 = x + y + z;   // ok
}

 

3. 중괄호 초기화를 사용하면 좋은 점

C++의 가장 성가신 구문 해석에서 자유롭다. ex) 함수연산자

class A
{
public:
    A() {}
};

int main()
{
    A a();  // 함수 연산자임, 객체 a를 만들고 기본 생성자 호출하는 것이 아님, 컴파일에러도 안남
    		// (A타입을 리턴하고 매개변수가 없는 a 함수)
    
    A a;    // 객체 a생성, 생성자 호출
}

class B
{
public:
    B(A a) {}
};

int main()
{
    B b(A());   // B를 리턴하는 b함수 호출
    B b{ A{} };   // A를 인자로 주고 B클래스 객체 b생성
}

 

4. 초기화 리스트

// Initialize List
class A_Initial
{
public:
	A_Initial(std::initializer_list<int> I_list)
	{
		for (auto itr = I_list.begin(); itr != I_list.end(); ++itr)
		{
			std::cout << "I_List_생성자\n";
		}
	}
	A_Initial(int a) {}
};

int main()
{
	A_Initial a{ 1,2,3,4,5 };

	A_Initial a(3.5);      // 형 변환
	A_Initial a{ 3.5 };    // 에러
}

 

int main()
{
    auto a = { 1 };     	// 첫 번째 형태이므로 std::initializer_list<int>
    auto b{ 1 };       	 	// 두 번째 형태이므로 그냥 int

    auto c = { 1,2 };   	// initializer_list
    auto d{ 1,2 };      	// 인자가 2개 이상이라 오류
    auto e = { 1,2,3.0 };   // std::initializer_list<T>의 T를 추론할 수 없어서 오류
    
    // 문자열
    auto list = { "a", "b", "c" };  		// initializer_list<const char*>

	// 다음과 같이 초기화하려면 using namespace std::literals; 를 추가해줘야함
    // (문자열 literal 연산자를 사용하기 위해)
    // using namespace std;도 가능 (std 안에 포함되어있음)
    auto list = { "a"s, "b"s, "c"s };  		// initializer_list<std::string>
}

 

5. 템플릿은 초기화 리스트에 대해서 추론이 되지 않음

// 템플릿은 초기화 리스트에 대해서 추론이 안된다.
template <typename T>
void foo(T param) {}

int main()
{
    // auto의 경우는 중괄호를 initializer_list로 추론
    auto x = { 11,23,9 };   // x의 타입은 std::initializer_list<int>

    // template의 T는 추론을 못함, 이것이 auto와 템플릿의 차이
    foo({ 11,23,9 });
}

// 따라서, 다음과 같이 특정시켜줘야 함
template <typename T>
void foo(std::initializer_list<int> T) {}

람다의 매개변수도 마찬가지로 initializer_list의 타입 추론이 안됨

 

 

함수의 반환형이 auto이고, 초기화 리스트를 반환하는 경우, 추론이 되지 않음

// 오류 {1,2,3} 타입 추론 안됨
auto createInitList(void)
{
    return { 1,2,3 };
}

 

6. vector를 초기화 리스트로 초기화

#include <vector>
int main()
{
    std::vector<int> v1(10, 20);        // 값이 20인 원소 10개 넣기 (총 10개)
    std::vector<int> v2{ 10, 20 };      // 10 넣기, 20 넣기 (총 2개)
}
저작자표시 비영리 변경금지 (새창열림)

'C, C++ > Modern C++' 카테고리의 다른 글

[C++ 11] noexcept  (1) 2022.06.27
[C++ 11] 복사 생략(Copy Elision)  (0) 2022.04.21
[C++] 스마트 포인터 참고할만한 글  (0) 2021.12.22
    'C, C++/Modern C++' 카테고리의 다른 글
    • [C++ 11] noexcept
    • [C++ 11] 복사 생략(Copy Elision)
    • [C++] 스마트 포인터 참고할만한 글
    종제로
    종제로

    티스토리툴바