[C++] uniform initialization
Updated:
개요
- {}를 사용하여 초기화
- ()가 함수 정의인지 호출인지 초기화인지 헷갈리는 기존의 문제를 해결
- 암시적 변환 불가능
- 의도하지 않은 타입 캐스팅에 의한 동작을 컴파일 타임에 방지
- {}는 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