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 |