Thinking Different







새로 추가된 알고리즘




C++17에서 새로 추가된 알고리즘들을 간략하게만 소개하겠다. 이들은 모두 std 이름공간에 속한다.


▶ for_each_n: for_each와 같되 [first, last)가 아니라 [first, first+n)을 입력 범위로 사용하며, first+n을 돌려준다(참고로 for_each의 직렬 버전은 사용자 지정 함수를 돌려주고 병렬 버전은 아무것도 돌려주지 않는다). 필요한 헤더는 <algorithm>이며, 병렬 버전도 있다.


 sample: 주어진 범위의 요소 n개를 주어진 확률 분포에 따라 무작위로 선택한다. 필요한 헤더는 <algorithm>이다.


 uninitialized_move와 uninitialized_move_n: 주어진 요소들을 초기화되지 않은 메모리 영역으로 이동한다. 필요한 헤더는 <memory>이며, 병렬 버전도 있다.


 clamp: 주어진 값이 하한보다 작으면 하한을, 상한보다 크면 상한을 돌려준다. 그 외에는 주어진 값을 돌려준다. 비교 함수를 지정할 수 있다. 필요한 헤더는 <algorithm>이다.


 reduce: 분산 처리나 병렬 처리 관련 프레임워크 또는 언어에서 흔히 볼 수 있는 Map-Reduce(사상-축약) 패턴의 Reduce 단계에 해당하는 알고리즘이다. 필요한 헤더는 <numeric>이며, 병렬 버전도 있다. 참고로 Map에 해당하는 표준 라이브러리 알고리즘은 transform이다. 기존 accumulate 알고리즘에 병렬 버전이 추가되지 않았는데, 대신 reduce의 병렬 버전을 사용하면 된다.


 transform_reduce: Map-Reduce에 해당하는 알고리즘으로, 요소들을 먼저 변환한 후에 축약한다. 필요한 헤더는 <numeric>이며, 병렬 버전도 있다. 기존 inner_product 알고리즘에 병렬 버전이 추가되지 않았는데, 대신 이 transform_reduce의 병렬 버전을 사용하면 된다.


 inclusive_scan과 exclusive_scan: 요소들의 구간 합(prefix sum; 또는 부분합)들을 구한다. inclusive_scan은 i번째 요소를 i번째 부분합에 포함하고, exclusive_scan은 포함하지 않는다. 예를 들어 덧셈과 초기치 0을 사용한다고 할 때 {1, 1, 0, 2, 3}의 inclusive_scan 결과는 {1, 2, 2, 4, 7}이고 exclusive_scan 결과는 {0, 1, 2, 2, 4}이다. 덧셈 이외의 합산 함수를 지정할 수 있으며, 부분합의 초기치도 다르게 지정할 수 있다(기본은 0). 필요한 헤더는 <numeric>이며, 병렬 버전도 있다. 기존 partial_sum 알고리즘에 병렬 버전이 추가되지 않았는데, 대신 inclusive_scan의 병렬 버전을 사용하면 된다.


 transform_inclusive_scan과 transform_inclusive_scan: 요소들을 먼저 변환한 후 구간 합을 구한다. 필요한 헤더는 <numeric>이며, 병렬 버전도 있다.



기타 변경 사항




그 외에 C++17 표준 라이브러리의 변경 사항을 정리하자면 다음과 같다.

 random_shuffle, auto_ptr, result_of, bind1st, unxepected 등 이전 표준들이 폐기 예정으로 분류한 구성요소들이 실제로 폐기되었다(표 A.3).


 활성 예외 객체 검출 함수 uncaught_exception이 폐기 예정으로 분류되고, 이를 대신하는 uncaught_exceptions가 추가되었다. 전자는 현재 스레드에 활성 예외 객체(던져졌지만 아직 해당 catch 절에 도달하지 않은 예외 객체)가 있는지의 여부(bool)를 돌려주지만, 후자는 현재 스레드의 활성 예외 객체 개수(int)를 돌려준다(<exception> 헤더).


 map과 unordered_map에 try_emplace와 insert_or_assign이라는 새로운 멤버 함수가 추가되었다. 이들은 주어진 키가 컨테이너에 없는 경우에만 새 요소를 생성 또는 삽입한다.


 컨테이너 멤버 함수 size, empty, data의 비멤버 함수 버전인 std::size, std::empty, std::data가 추가되었다(<iterator> 헤더).


 메모리를 구성하는 바이트byte의 개념을 좀 더 명시적으로 표현하기 위해 std::byte라는 형식이 추가되었다. 내부적으로 std::byte는 하나의 열거형 클래스(enum class)인데, 바탕 자료 형식은 unsigned char이다. unsigned char와는 달리 std::byte는 문자 형식으로도, 수치(산술) 형식으로도 간주되지 않는다. 개념적으로 std::byte는 단지 비트들의 집합일 뿐이며, 산술 연산자들은 지원하지 않고 비트별 논리 연산자들과 자리이동(shift) 연산자들만 지원한다. 임의의 정수 n을 std::byte 객체로 변환하려면 std::byte{n} 형태의 표현식을 사용하고(C++17부터는 이런 식으로 열거형 객체를 생성할 수 있게 되었다), 그 반대의 변환은 std::to_integer 함수(역시 C++17에서 추가되었다)를 사용하면 된다.


 컴파일 시점에서 형식 특질들의 논리합, 논리곱, 부정을 산출하는 메타 함수 conjunction, disjunction, negation이 추가되었으며, is_aggregate, is_invocable, is_swappable 등 다양한 컴파일 시점 형식 판정 함수가 추가되었다(<type_traits> 헤더).


 최대공약수와 최소공배수를 돌려주는 수학 함수 gcd와 lcm이 추가되었으며(<numeric> 헤더), 타원적분, 베셀 함수, 르장드르 함수, 노이만 함수, 리만 제타 함수 등 다양한 특수 함수가 추가되었다(<cmath> 헤더). 표 A.4에 특수 함수들이 나열되어 있다.



표 A.3 폐기된 구성요소들


auto_ptr, const_mem_fun_t, pointer_to_binary_function, binary_function, get_unexpected, pointer_to_unary_function, bind1st, mem_fun1_ref_t, ptr_fun, bind2nd, mem_fun1_t, random_shuffle, binder1st, mem_fun_ref_t, set_unexpected, binder2nd, mem_fun_ref, unary_function, const_mem_fun1_ref_t, mem_fun_t, unexpected, const_mem_fun1_t, mem_fun, unexpected_handler, const_mem_fun_ref_t



표 A.4 특수 수학 함수



assoc_laguerre, comp_ellint_3f, ellint_1l, legendre, assoc_laguerref, comp_ellint_3l, ellint_2, legendref, assoc_laguerrel, cyl_bessel_i, ellint_2f, legendrel, assoc_legendre, cyl_bessel_if, ellint_2l, riemann_zeta, assoc_legendref, cyl_bessel_il, ellint_3, riemann_zetaf, assoc_legendrel, cyl_bessel_j, ellint_3f, riemann_zetal, beta, cyl_bessel_jf, ellint_3l, sph_bessel, betaf, cyl_bessel_jl, expint, sph_besself, betal, cyl_bessel_k, expintf, sph_bessell, comp_ellint_1, cyl_bessel_kf, expintl, sph_legendre,comp_ellint_1f, cyl_bessel_kl, hermite, sph_legendref, comp_ellint_1l, cyl_neumann, hermitef, sph_legendrel, comp_ellint_2, cyl_neumannf, hermitel, sph_neumann,comp_ellint_2f, cyl_neumannl, laguerre, sph_neumannf, comp_ellint_2l, ellint_1, laguerref, sph_neumannl, comp_ellint_3, ellint_1f, laguerrel




출처 : 류광의 번역이야기