rooni
rooni

Reputation: 1090

STL std::transform

The transform() algorithm has two forms, i am fine with the first one.

Here is the template specification for the second one:

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

My book says,

In the second form, the transformation is applied using a binary operator function that receives the value of an element from the sequence to be transformed as in its first parameter and an element from the second sequence as its second parameter.

q1. Why is there no input iterator parameter for the second sequence indicating the end of second sequence? i.e Why is there no InputIterator last2 parameter in the transform()?

q2. What happens when the length of the first and second sequence is unequal?

q3. The blockquoted text says binary operator function. So what does that operator function mean in this context? Isn't any binary function valid?

Upvotes: 2

Views: 276

Answers (2)

Christian Hackl
Christian Hackl

Reputation: 27528

q1. Why is there no input iterator parameter for the second sequence indicating the end of second sequence?

Because the second sequence must be at least as long as the first one anyway. The algorithm knows that its work is done when the first sequence's end is reached.

q2. What happens when the length of the first and second sequence is unequal?

You get undefined behaviour if the second sequence is shorter than the first one. Otherwise, if the second one is longer, nothing bad happens; the rest of the elements will simply be ignored.

q3. The blockquoted text says binary operator function. So what does that operator function mean in this context?

Its first argument is element N from the first sequence, its second argument is element N from the second sequence. It can be anything that can be called like that, e.g. a plain function, a function-like object such as std::function, a lambda, something bound via std::bind and so on. The only thing that matters is that it can be called with the () syntax.

I recommend some Internet research on "function objects" and "functors".

Upvotes: 4

lisyarus
lisyarus

Reputation: 15522

This version of transform transforms two sequences into one. Say, if the operation if op, then the pair of sequences

[a, b, c, d]

[e, f, g, h]

is transformed into

[op(a, e), op(b, f), op(c, g), op(d, h)]

A possible simple implementation is

for (; first1 != last1; ++first1, ++first2)
{
    *result++ = binary_op(*first1, *first2);
}

Now, to your questions.

  1. Obviously, the lengths of the two sequences must coincide for the algorithm to work. Thus, if it knows the length of the first sequence, it automatically knows the length of the second sequence, so it knows where to stop while iterating. It looks roughly like this:

  2. If the length of the second sequence is bigger, the algorithm just doesn't use the rest. If the length of the first sequence is smaller, it is undefined behavoir.

  3. Yes, it can be anything callable with appropriate arguments using the function call operator: a function pointer, a function object, a lambda, etc.

Upvotes: 1

Related Questions