Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best STL transform - like template function for ternary operators

Tags:

c++

algorithm

stl

STL defines two flavors of the transform function

The first is For unary operators:

template <class InputIterator, class OutputIterator, class UnaryOperation>
OutputIterator transform (InputIterator first1, InputIterator last1,
                                OutputIterator result, UnaryOperation op);

And the second is for binary operators:

template <class InputIterator1, class InputIterator2,
          class OutputIterator, class BinaryOperation>
  OutputIterator transform (InputIterator1 first1, InputIterator1 last1,
                            InputIterator2 first2, OutputIterator result,
                            BinaryOperation binary_op);

What is the most efficient implementation of a similiar function for a ternary operator?

EDIT: Here is the trivial implementation I came up with, but isn't there a leaner and more elegant solution?

template <class InputIterator1, class InputIterator2, class InputIterator3,
          class OutputIterator, class TrenaryOperation>
  OutputIterator transform3(InputIterator1 first1, InputIterator1 last1,
                            InputIterator2 first2, InputIterator3 first3, OutputIterator result,
                            TrenaryOperation trenary_op)
{
  while (first1 != last1) {
    *result = trenary_op(*first1, *first2, *first3);
    ++result; ++first1; ++first2; ++first3;
  }
  return result;
}
like image 534
zr. Avatar asked Oct 01 '22 14:10

zr.


1 Answers

A simple version of this can be achieved to create an n-ary transform like this:

    template <class Functor, class OutputIterator,
              class Input1, class ... Inputs>
    OutputIterator transform(Functor f, OutputIterator out,
                             Input1 first1, Input1 last1,
                             Inputs ... inputs)
    {
        while(first1 != last1)
            *out++ = f(*first1++, *inputs++...);
        return out;
    }

This version tries to stay as close to the existing transform as possible, taking one first/last pair of iterators and the rest are just firsts. This leaves it up to the user to make sure all the ranges are valid, just as with the binary-transform.

As for performance, I agree with ShighShagh's comment about performance not likely being an issue here. The compiler will be in a better place than you to determine what optimizations to take because each instantiation could lead to different situations that the programmer couldn't possibly know while writing this function.

like image 159
SirGuy Avatar answered Oct 06 '22 00:10

SirGuy