더북(TheBook)

반복자는 컨테이너의 원소들을 특정해서 가리키기만 할 뿐, 컨테이너 자체에 대한 정보는 전혀 알지 못한다. 따라서 반복자가 가리키는 원소가 array 컨테이너에 있는지, vector 컨테이너에 있는지 반복자가 알려줄 방법은 없다. 컨테이너에 있는 원소들의 범위를 지정하는 반복자가 있으면 이들 반복자에 알고리즘을 적용할 수 있는 가능성이 열린다. 그렇다면 Ex2_01.cpp에 알고리즘을 사용할 수 있을까? algorithm 헤더에 정의된 generate() 함수 템플릿을 이용하면 함수 객체가 계산한 값으로 범위를 초기화할 수 있다. 따라서 height_ins 컨테이너를 초기화하는 부분은 다음과 같이 재작성할 수 있다.

unsigned int height {}; // 현재 키를 초기화 값으로 저장한다
std::generate(std::begin(height_ins), std::end(height_ins),
            [height, &min_ht, &ht_step]() mutable
                    { return height += height == 0 ? min_ht : ht_step; });

컨테이너 원소에 값을 설정하는 작업은 이제 두 문장으로 줄었고, 루프도 사용하지 않는다. 첫 번째 문장은 변수를 정의하고 원소를 초기화한다. generate() 함수는 값을 설정할 범위로 시작 반복자와 끝 반복자를 처음 두 인수로 받고, 값을 생성할 함수를 세 번째 인수로 받는다. 여기서는 세 번째 인수에 람다 표현식을 썼다. min_htht_step 변수는 람다 표현식에서 참조로 캡처했고 mutable 키워드가 있으므로 람다 표현식에서 값으로 캡처한 height의 로컬 복제본의 값을 변경할 수 있다. return 문에서 로컬 복제본 height는 첫 번째 실행에는 min_ht로 설정되고, 두 번째 실행부터는 ht_step만큼 증가하게 된다. 람다 표현식에서 값으로 캡처한 변수의 로컬 복제본의 값은 람다 표현식의 실행에서 다음 실행으로 값이 유지된다. 이를 이용하면 우리가 원하는 대로 동작하게 할 수 있다.

array 컨테이너를 연속값으로 초기화하고 싶다고 하자. 이럴 때는 numeric 헤더에 있는 iota() 함수를 쓸 수 있다. 사용법은 다음과 같다.

std::array<double, 10> values;
std::iota(std::begin(values), std::end(values), 10.0); // 원소들의 값을 10.0부터 19.0까지 설정
 

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.