According to cplusplus.com, std::transform
applies an operation sequentially to the elements of one (1) or two (2) ranges and stores the result in the range that begins at result. The last argument of std::transform
is generally a function, which does some operation on the elements of the first container, but suppose I have a functor object as follows :
struct functor {
functor(int x) : x(x) {}
int operator()(int x1) {return x + x1;}
private :
int x;
}
Then, in place of a function, I can also pass the instance of functor, like this :
vector<int> v1, v2;
v1.push_back(1);
v1.push_back(2);
v2.resize(v1.size());
std::transform(v1.begin(), v1.end(), v2.begin(), functor(1));
My question is, how does the compiler know whether a function or an instance of a functor class in passed to the std::transform
function ? Also, if an instance is passed, what happens internally, regarding applying the function to the elements of the first container ?
std::transform
is a template (well, two overloads for one or two input ranges) function which possible implementation for one range:
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;
}
and for two ranges
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;
}
The requirements on the last argument is that it has an operator ()
applicable to types that you get by dereferencing provided iterators (i.e. its arguments and return type are implicitly convertible to them). So it could be plain function, lambda, or any user type with such operator.