프로그래밍 일반 2014. 4. 9. 18:14

C++ 11 Initializer lists 초기화자 리스트

웹 컴파일러 링크 : http://melpon.org/wandbox/


std::vector<double> v = { 1, 2, 3.456, 99.99 };

std::list<std::pair<std::string,std::string>> languages = {

{”Nygaard”,”Simula”}, 

{”Richards”,”BCPL”},

{”Ritchie”,”C”}

};


std::map<std::vector<std::string>,std::vector<int>> years = {

{ {”Maurice”,”Vincent”, ”Wilkes”},{1913, 1945, 1951, 1967, 2000} },

{ {”Martin”, ”Ritchards”}, {1982, 2003, 2007} },

{ {”David”, ”John”, ”Wheeler”}, {1927, 1947, 1951, 2004} }

};


초기화자 리스트는 단순히 배열만을 위해 사용되는 것은 아니다. {} 리스트를 받는 메커니즘은 std::initializer_list<T> 를 인자로 받는 함수(많은 경우 생성자)와 같다. 예를 들어


void Func(std::initializer_list<int>);


Func({1,2});

Func( { 23, 2344, 23434, 23523} );

Func( {} ); // 비어 있는 리스트

Func{1, 2}; // 오류 : 함수 호출 ()가 없다.


years.insert( {{”Martin”, ”Ritchards”}, {1982, 2003, 2007}} );


초기화자 리스트는 임의의 길이가 될 수 있지만 모두 같은 타입이어야 한다. ( 즉 모든 원소들이 템플릿 인자 타입 T 이거나, T 로 변환될 수 있어야 한다. )


template<class T> class vector {

public:

vector (std::initializer_list<T> s) // 초기화자 리스트 생성자

{

reserve(s.size()); // 올바른 크기의 공간을 얻는다

// 원소들을 초기화 한다. (elem[0:s.size()) 안에 있는 것들을)

uninitialized_copy(s.begin(), s.end(), elem);

sz = s.size(); // vector 크기를 설정한다

}

// ... as before ...

};


직접적으로 초기화하는 것과 복사 초기화하는 것의 차이는 {}를 이용한 초기화에서도 마찬가지로 적용된다.

예를 들어 std::vector 에는 int 로 부터 생성하는 명시적 생성자와 초기화자 리스트 생성자가 있다.


std::vector<int> v1(10); // 가능 : v1에는 10개의 원소가 있다.

v1 = 10; // 오류 : 허용되는 변환이 없다.


std::vector<int> v2 = 10; // 오류 : int 를 std::vector<int> 로 변환할 수 없다.


void Func( const std::vector<int>& );


Func( 9 ); // 오류 : int 를 std::vector<int> 로 변환할 수 없다.


std::vector<int> v1{10}; // 가능 : v1에는 1개의 원소가 있다 (값이 10)


v1 = {9}; // v1 에는 1개의 원소가 있다. (값이 9)


Func( {9} ); // Func는 리스트 {9} 로 호출



std::vector<std::vector<int>> vs = {

std::vector<int>(10), // 가능 : 명시적 생성 (10 개의 원소)

std::vector<int>{10}, // 가능 : 명시적 생성 (값이 10 인 1 개의 원소)

10 // 오류 : vector 의 생성자는 명시적

};


함수는 initializer_list 를 인자로 접근할 수 있다. 예를 들어


void f(initializer_list<int> args)

{

for (auto p=args.begin(); p!=args.end(); ++p) cout << *p << "\n";

}


참고 :