Defined in header
Call signature
template<std::input_iteratorI,std::sentinel_for<I>S,std::weakly_incrementableO,std::copy_constructibleF,classProj=std::identity>requiresstd::indirectly_writable<O,std::indirect_result_t<F&,std::projected<I,Proj>>>constexprranges::unary_transform_result<I,O>transform(Ifirst1,Slast1,Od_first,Funary_op,Projproj1={}); (1) (since C++20)template<ranges::input_rangeR,std::weakly_incrementableO,std::copy_constructibleF,classProj=std::identity>requiresstd::indirectly_writable<O,std::indirect_result_t<F&,std::projected<ranges::iterator_t<R>,Proj>>>constexprranges::unary_transform_result<ranges::borrowed_iterator_t<R>,O>transform(R&&r1,Od_first,Funary_op,Projproj1={}); (2) (since C++20)template<std::input_iteratorI1,std::sentinel_for<I1>S1,std::input_iteratorI2,std::sentinel_for<I2>S2,std::weakly_incrementableO,std::copy_constructibleF,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_writable<O,std::indirect_result_t<F&,std::projected<I1,Proj1>,std::projected<I2,Proj2>>>constexprranges::binary_transform_result<I1,I2,O>transform(I1first1,S1last1,I2first2,S2last2,Od_first,Fbinary_op,Proj1proj1={},Proj2proj2={}); (3) (since C++20)template<ranges::input_rangeR1,ranges::input_rangeR2,std::weakly_incrementableO,std::copy_constructibleF,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_writable<O,std::indirect_result_t<F&,std::projected<ranges::iterator_t<R1>,Proj1>,std::projected<ranges::iterator_t<R2>,Proj2>>>constexprranges::binary_transform_result<ranges::borrowed_iterator_t<R1>,ranges::borrowed_iterator_t<R2>,O>transform(R1&&r1,R2&&r2,Od_first,Fbinary_op,Proj1proj1={},Proj2proj2={}); (4) (since C++20)template</*execution-policy*/Ep,std::random_access_iteratorI,std::sized_sentinel_for<I>S,std::random_access_iteratorO,std::sized_sentinel_for<O>OutS,std::copy_constructibleF,classProj=std::identity>requiresstd::indirectly_writable<O,std::indirect_result_t<F&,std::projected<I,Proj>>>ranges::unary_transform_result<I,O>transform(Ep&&policy,Ifirst1,Slast1,Od_first,OutSd_last,Funary_op,Projproj1={}); (5) (since C++26)template</*execution-policy*/Ep,/*sized-random-access-range*/R,/*sized-random-access-range*/OutR,std::copy_constructibleF,classProj=std::identity>requiresstd::indirectly_writable<ranges::iterator_t<OutR>,std::indirect_result_t<F&,std::projected<ranges::iterator_t<R>,Proj>>>ranges::unary_transform_result<ranges::borrowed_iterator_t<R>,ranges::borrowed_iterator_t<OutR>>transform(Ep&&policy,R&&r1,OutR&&d_r,Funary_op,Projproj1={}); (6) (since C++26)template</*execution-policy*/Ep,std::random_access_iteratorI1,std::sized_sentinel_for<I1>S1,std::random_access_iteratorI2,std::sized_sentinel_for<I2>S2,std::random_access_iteratorO,std::sized_sentinel_for<O>OutS,std::copy_constructibleF,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_writable<O,std::indirect_result_t<F&,std::projected<I1,Proj1>,std::projected<I2,Proj2>>>ranges::binary_transform_result<I1,I2,O>transform(Ep&&policy,I1first1,S1last1,I2first2,S2last2,Od_first,OutSd_last,Fbinary_op,Proj1proj1={},Proj2proj2={}); (7) (since C++26)template</*execution-policy*/Ep,/*sized-random-access-range*/R1,sized-random-access-range*/R2,/*sized-random-access-range*/OutR,std::copy_constructibleF,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_writable<ranges::iterator_t<OutR>,std::indirect_result_t<F&,std::projected<ranges::iterator_t<R1>,Proj1>,std::projected<ranges::iterator_t<R2>,Proj2>>>ranges::binary_transform_result<ranges::borrowed_iterator_t<R1>,ranges::borrowed_iterator_t<R2>,ranges::borrowed_iterator_t<OutR>>transform(Ep&&policy,R1&&r1,R2&&r2,OutR&&d_r,Fbinary_op,Proj1proj1={},Proj2proj2={}); (8) (since C++26)Helper types
template<classI,classO>usingunary_transform_result=ranges::in_out_result<I,O>; (9) (since C++20)template<classI1,classI2,classO>usingbinary_transform_result=ranges::in_in_out_result<I1,I2,O>; (10) (since C++20)For the definition of /*execution-policy*/, see
; for the definition of /*sized-random-access-range*/, see
.
Applies the given function to the (projected) elements of the given source range(s), and stores the result in the destination range.
1-4) The destination range is [d_first, ranges::next(d_first,count)), where count is defined below.
1,2) There is only one source range, and the unary operation unary_op is applied to each of its elements (projected by proj1).
1) The source range is [first1, last1), and count is ranges::distance(first1,last1).
2) The source range is r1, and count is ranges::distance(r1).
3,4) There are two source ranges, and the binary operation binary_op is applied to each pair of their corresponding elements (projected by proj1 and proj2 respectively).
3) The two source ranges are [first1, last1) and [first2, last2), and count is the lesser of ranges::distance(first1,last1) and ranges::distance(first2,last2).
4) The two source ranges are r1 and r2, and count is the lesser of ranges::distance(r1) and ranges::distance(r2).
5-8) Same as (1-4), but executed according to policy, and the destination range is [d_first, d_last) or d_r. If the destination range is exhausted before reaching the end of any source range, the remaining elements in the source range(s) will not be transformed.
If unary_op or binary_op invalidates an iterator or subrange, or modifies an element in any of the following ranges, the behavior is undefined:
[first1, last1]
[r1.begin(), ranges::next(r1.begin(),r1.end())]
[first2, last2]
[r2.begin(), ranges::next(r2.begin(),r2.end())]
[d_first, ranges::next(d_first,count)] (count is defined above)
[d_first, d_last]
[d_r.begin(), ranges::next(d_r.begin(),d_r.end())]
The function-like entities described on this page are
(informally known as niebloids), that is:
Explicit template argument lists cannot be specified when calling any of them.
None of them are visible to
.
When any of them are found by
as the name to the left of the function-call operator,
is inhibited.
Parameters
first1, last1 - the iterator-sentinel pair defining the first source
r1 - the first source range first2, last2 - the iterator-sentinel pair defining the second source
r2 - the second source range d_first - the beginning of the destination range d_last - the sentinel of the destination range d_r - the destination range unary_op, binary_op - operation to apply to the projected element(s) proj1 - the projection to be applied to the elements in the first source range proj2 - the projection to be applied to the elements in the second source range policy - the
to use Return value
1,2,5,6) A ranges::unary_transform_result object where:
The data member
holds an iterator past the last transformed element in the source range, or an iterator to the beginning of the source range if no element is transformed.
The data member
holds an iterator past the last assigned element in the destination range, or an iterator to the beginning of the destination range if no element is transformed.
3,4,7,8) A ranges::binary_transform_result object where:
The data member
holds an iterator past the last transformed element in the first source range, or an iterator to the beginning of the first source range if no element is transformed.
The data member
holds an iterator past the last transformed element in the second source range, or an iterator to the beginning of the second source range if no element is transformed.
The data member
holds an iterator past the last assigned element in the destination range, or an iterator to the beginning of the destination range if no element is transformed.
Complexity
Given
N1 as ranges::distance(first1,last1) or ranges::distance(r1),
N2 as ranges::distance(first2,last2) or ranges::distance(r2), and
N3 as ranges::distance(d_first,d_last) or ranges::distance(d_r):
1,2) Exactly N1 applications of unary_op and proj1.
3,4) Exactly min(N1,N2) applications of binary_op, proj1 and proj2.
5,6)𝓞(min(N1,N3)) applications of unary_op and proj1.
7,8)𝓞(min(N1,N2,N3)) applications of binary_op, proj1 and proj2.
Exceptions
5-8) During the execution process:
If the temporary memory resources required for parallelization are not available,
is thrown.
If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for
,
is invoked).
Notes
ranges::transform does not guarantee in-order application of unary_op or binary_op. To apply a function to a sequence in-order or to apply a function that modifies the elements of a sequence, use
.
Possible implementation
structtransform_fn{// First versiontemplate<std::input_iteratorI,std::sentinel_for<I>S,std::weakly_incrementableO,std::copy_constructibleF,classProj=std::identity>requiresstd::indirectly_writable<O,std::indirect_result_t<F&,std::projected<I,Proj>>>constexprranges::unary_transform_result<I,O>operator()(Ifirst1,Slast1,Od_first,Funary_op,Projproj1={})const{for(;first1!=last1;++first1,(void)++result)*result=std::invoke(unary_op,std::invoke(proj1,*first1));return{std::move(first1),std::move(d_first)};}template<ranges::input_rangeR>constexprautoget_end(R&&r){returnranges::end(r);}template<ranges::forward_rangeR>constexprautoget_end(R&&r){returnranges::next(ranges::begin(r),ranges::end(r));}// Second versiontemplate<ranges::input_rangeR,std::weakly_incrementableO,std::copy_constructibleF,classProj=std::identity>requiresstd::indirectly_writable<O,std::indirect_result_t<F&,std::projected<ranges::iterator_t<R>,Proj>>>constexprranges::unary_transform_result<ranges::borrowed_iterator_t<R>,O>operator()(R&&r1,Od_first,Funary_op,Projproj1={})const{return(*this)(ranges::begin(r1),get_end(r1),std::move(d_first),std::move(unary_op),std::move(proj1));}// Third versiontemplate<std::input_iteratorI1,std::sentinel_for<I1>S1,std::input_iteratorI2,std::sentinel_for<I2>S2,std::weakly_incrementableO,std::copy_constructibleF,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_writable<O,std::indirect_result_t<F&,std::projected<I1,Proj1>,std::projected<I2,Proj2>>>constexprranges::binary_transform_result<I1,I2,O>operator()(I1first1,S1last1,I2first2,S2last2,Od_first,Fbinary_op,Proj1proj1={},Proj2proj2={})const{for(;first1!=last1&&first2!=last2;++first1,(void)++first2,(void)++result)*result=std::invoke(binary_op,std::invoke(proj1,*first1),std::invoke(proj2,*first2));return{std::move(first1),std::move(first2),std::move(d_first)};}// Fourth versiontemplate<ranges::input_rangeR1,ranges::input_rangeR2,std::weakly_incrementableO,std::copy_constructibleF,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_writable<O,std::indirect_result_t<F&,std::projected<ranges::iterator_t<R1>,Proj1>,std::projected<ranges::iterator_t<R2>,Proj2>>>constexprranges::binary_transform_result<ranges::borrowed_iterator_t<R1>,ranges::borrowed_iterator_t<R2>,O>operator()(R1&&r1,R2&&r2,Od_first,Fbinary_op,Proj1proj1={},Proj2proj2={})const{return(*this)(ranges::begin(r1),get_end(r1),ranges::begin(r2),get_end(r2),std::move(d_first),std::move(binary_op),std::move(proj1),std::move(proj2));}};inlineconstexprtransform_fntransform;Example
The following code uses ranges::transform to convert a string in place to uppercase using the std::toupper function and then transforms each char to its ordinal value. Then ranges::transform with a projection is used to transform elements of std::vector<Foo> into chars to fill a
.
Run this code
#include<algorithm>#include<cctype>#include<functional>#include<iostream>#include<string>#include<vector>intmain(){std::strings{"hello"};autoop=[](unsignedcharc)->unsignedchar{returnstd::toupper(c);};namespaceranges=std::ranges;// uppercase the string in-placeranges::transform(s.begin(),s.end(),s.begin(),op);std::vector<std::size_t>ordinals;// convert each char to size_tranges::transform(s,std::back_inserter(ordinals),[](unsignedcharc)->std::size_t{returnc;});std::cout<<s<<':';for(autoord:ordinals)std::cout<<' '<<ord;// double each ordinalranges::transform(ordinals,ordinals,ordinals.begin(),std::plus{});std::cout<<'\n';for(autoord:ordinals)std::cout<<ord<<' ';std::cout<<'\n';structFoo{charbar;};conststd::vector<Foo>f={{'h'},{'e'},{'l'},{'l'},{'o'}};std::stringresult;// project, then uppercaseranges::transform(f,std::back_inserter(result),op,&Foo::bar);std::cout<<result<<'\n';}Output:
HELLO: 72 69 76 76 79 144 138 152 152 158 HELLO See also