개요
- {}를 사용하여 초기화
- ()가 함수 정의인지 호출인지 초기화인지 헷갈리는 기존의 문제를 해결
- 암시적 변환 불가능
- 의도하지 않은 타입 캐스팅에 의한 동작을 컴파일 타임에 방지
- {}는 initializer_list를 인자로 받는 생성자를 최우선으로 호출하므로 다른 생성자를 호출하려면 ()를 사용
- auto는 initializer_list로 판단
- 문자열의 경우
initializer_list<const char*>로 판단하므로 initializer_list<string>로 판단하려면 literals 사용
예제
- 코드
#include <cstring>
#include <iostream>
#include <string>
#include <typeinfo>
#include <vector>
using namespace std;
class Test {
public:
Test(int i) { cout << i << endl; }
};
template <typename T> constexpr string type_name() {
const string s = __PRETTY_FUNCTION__;
const int prefixSize = s.find("[with T = ") + strlen("[with T = ");
return string(s.data() + prefixSize, s.find(';') - prefixSize);
}
int main() {
Test t(1.1);
// Test t{1.1};
cout << "------ 1" << endl;
auto f1 = [](int i) -> Test { return (i); };
f1(2);
cout << "------ 2" << endl;
auto f2 = [](int i) -> Test { return {i}; };
f2(3);
cout << "------ 3" << endl;
auto f3 = [](initializer_list<int> l) {
for (const auto &iter : l) {
cout << iter << endl;
}
};
// f3((1, 2, 3));
f3({1, 2, 3});
cout << "------ 4" << endl;
vector<int> v = {1, 2, 3};
for (const auto &iter : v) {
cout << iter << endl;
}
cout << "------ 5" << endl;
auto l1 = {1};
cout << type_name<decltype(l1)>() << endl;
cout << "------ 6" << endl;
auto l2{1};
cout << type_name<decltype(l2)>() << endl;
cout << "------ 7" << endl;
auto l3 = {1, 2, 3};
cout << type_name<decltype(l3)>() << endl;
cout << "------ 8" << endl;
auto l5 = {"a", "b"};
cout << type_name<decltype(l5)>() << endl;
cout << "------ 9" << endl;
/* compile error
auto l4{1, 2};
cout << typeid(l4).name() << endl;
*/
return 0;
}
- 실행 결과
1
------ 1
2
------ 2
3
------ 3
1
2
3
------ 4
1
2
3
------ 5
std::initializer_list<int>
------ 6
int
------ 7
std::initializer_list<int>
------ 8
std::initializer_list<const char*>
------ 9