모두의 코드
C++ 레퍼런스 - transform 함수
transform
<algorithm> 에 정의됨
template <class InputIt, class OutputIt, class UnaryOperation> OutputIt transform(InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op); // (1) template <class InputIt1, class InputIt2, class OutputIt, class BinaryOperation> OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2, OutputIt d_first, BinaryOperation binary_op); // (2) template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class ForwardIt3, class BinaryOperation> ForwardIt3 transform(ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, ForwardIt3 d_first, BinaryOperation binary_op); // (3)
std::transform 은 범위 내 (first
부터 last
전 까지) 원소들 각각에 대해 인자로 전달한 함수를 실행 한 후, 그 결과를 d_first
에서 부터 쭉 기록한다.
단항 함수
unary_op
이first1
부터last1
전까지 원소들을 인자로 전달하여 실행합니다.이항 함수
binary_op
이first1
부터last1
전까지 원소들과first2
부터의 원소들을 쌍으로 전달해서 실행합니다. 예를 들어서first1
부터last1
이 {1,2,3} 이고first2
부터의 원소가 {4,5,6} 이면binary_op
에는bianry_op(1,4), binary_op(2,5), binary_op(3,6)
이 실행되는 셈입니다.어떠한 방식으로 실행 시킬지. 지정할 수 있습니다.
ExecutionPolicy
참조.
인자들
first1, last1
: transform
을 적용할 원소들을 가리키는 범위first2
: 두 번째 인자들의 시작d_first
: 결과를 저장할 범위.first1
이나first2
와 동일해도 된다.policy
: 어떠한 방식으로 실행 시킬지.ExecutionPolicy
참조.unary_op
: 원소들을 전달할 단항 함수. 해당 함수는 다음과 같이 생겨야 합니다.
Ret unary(const Type &a);
참고로 함수의 인자로 굳이 const&
일 필요는 없습니다. Type
는 InputIt
의 역참조된 타입과 같거나 Type
로 변환될 수 있어야 하며, Ret 의 경우 OutputIt
의 역참조 된 타입이거나, Ret 에 변환되서 대입할 수 있어야 합니다.
binary_op
: 원소를 두 개 받는 이항 함수로 해당 함수는 아래와 같이 생겼습니다.
Ret binary(const Type1 &a, const Type2 &b);
함수의 인자로 굳이 const&
가 아니여도 됩니다. 위의 경우와 비슷하게 InputIt1
과 InputIt2
의 역참조 타입이 Type1
과 Type2
와 각각 같거나 해당으로 변환될 수 있어야만 합니다.
std::for_each 과의 관계
참고로 for_each 함수도 transform 함수와 하는 일은 거의 동일합니다. for_each 함수 역시, 범위 내에 원소들에 대해 전달된 함수를 호출하게 됩니다. 다만, 두 함수가 하는 역할은 조금 다른데
for_each 의 경우 원소를 수정하지 않습니다. 물론 전달한 함수가 레퍼런스를 받는다면 수정할 수 있겟지만, 바람직한 사용 방식은 아닙니다. 또한 함수의 리턴값 역시 무시됩니다. 참고로 for_each 는 표준에 의해 원소들을 순서대로 접근함이 보장됩니다.
transform 의 경우 원소를 수정하게 됩니다. 함수의 리턴값으로 해당 원소가 바뀝니다. 또한 for_each 와는 다르게, 순서대로 원소를 접근함이 보장되지 않습니다 (물론 범위 내에 원소를 모두 접근하기는 하지만, 꼭 처음부터 끝까지 순서대로 하는 것은 아니라는 의미입니다).
실행 예제
// 아래 예제는 문자열을 대문자로 바꾸거나, 해당 아스키 값으로 바꿉니다. #include <algorithm> #include <cctype> #include <iostream> #include <string> #include <vector> int main() { std::string s("hello"); std::transform( s.begin(), s.end(), s.begin(), [](unsigned char c) -> unsigned char { return std::toupper(c); }); std::vector<std::size_t> ordinals; std::transform(s.begin(), s.end(), std::back_inserter(ordinals), [](unsigned char c) -> std::size_t { return c; }); std::cout << s << ':'; for (auto ord : ordinals) { std::cout << ' ' << ord; } }
실행 결과
HELLO: 72 69 76 76 79
구현 예시
template <class InputIt, class OutputIt, class UnaryOperation> OutputIt transform(InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op) { while (first1 != last1) { *d_first++ = unary_op(*first1++); } return d_first; } template <class InputIt1, class InputIt2, class OutputIt, class BinaryOperation> OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2, OutputIt d_first, BinaryOperation binary_op) { while (first1 != last1) { *d_first++ = binary_op(*first1++, *first2++); } return d_first; }
참고 자료
for_each : 범위 내에 원소들에 대해 함수를 실행시킵니다.
댓글을 불러오는 중입니다..