Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no std::transform_n function in the C++ standard library?

I can find no mention of a transform_n function in draft N4431 of the C++ standard.

Is this intentional? If not, how would one go about suggesting this for a future version of the standard?

Here is how I would implement it:

    template<typename _InputIterator, typename Size, typename _OutputIterator, typename _UnaryOperation>
_OutputIterator transform_n(_InputIterator __first, Size __n, _OutputIterator __result, _UnaryOperation __op) {
    for(Size i=0;i<__n;++i)
        *__result++ = __op(*__first++);
    return __result;
}


template<typename _InputIterator1, typename Size, typename _InputIterator2, typename _OutputIterator, typename _BinaryOperation>
_OutputIterator transform_n(_InputIterator1 __first1, Size __n, _InputIterator2 __first2, _OutputIterator __result, _BinaryOperation __binary_op) {
    for(Size i=0;i<__n;++i)
        *__result++ = __binary_op(*__first1++, *__first2++);
    return __result;
}
like image 580
Stephen DeSalvo Avatar asked May 28 '15 03:05

Stephen DeSalvo


1 Answers

Here's another possible implementation, which shows that there is already a library function with equivalent functionality:

template<typename _InputIterator,
         typename _OutputIterator,
         typename _UnaryOperation>
_OutputIterator transform_n(_InputIterator __first,
                            size_t __n,
                            _OutputIterator __result,
                            _UnaryOperation __op) {
      return std::generate_n(__result, __n,
                             [&__first, &__op]() -> decltype(auto) {
                                return __op(*__first++);
                             });
}

As @TonyD mentions in a comment, this has the effect of forcing the transformation to happen in order, but that would already be the case if the input iterator argument is really just an input iterator.

Edit: As per the suggestion by @T.C., I changed the lambda to have a return type of decltype(auto), which (if I understand correctly) could allow move semantics through the output iterator. That requires a recent compiler, since it's a C++14 feature.

like image 85
rici Avatar answered Sep 25 '22 23:09

rici