I am currently doing some exercises with templated functions. I had the task to write a implementation of the transform algorithm. I did it like the following and it works:
template <class in, class out, class T>
out stransform(in b, in e, out d, T p(const T&)) {
    while (b != e) 
        *d++ = p(*b++);
    return d;
}
As with the normal transform I have to call the predicate with an explicit type like
stransform(begin(vec1), end(vec1), back_inserter(vec2), predi<double>);
Now, I stumbled upon the C++11 Lambdas and wanted to call my function like this:
stransform(begin(vec1), end(vec1), back_inserter(vec2), [] (double x) ->double {return x * 10;} );
With that I do get a compiler error that the type cant be deduced. This is the thing I dont understand as I am defining the T type in my lambda actually twice.
I did also check back the original transform function, with which it is working. I then checked the implementation of that one and it is obviously implemented with a template class for the whole function. Is that the correct way for implementing predicates with templates?
The predicate is normally a simple template argument:
template <class in, class out, class UnaryPredicate>
out stransform(in b, in e, out d, UnaryPredicate p); 
This will accept pointers to function, lambdas and function objects.
T p(const T&) is the type of a function which takes a T by reference. Your lambda takes its argument by value.
stransform (
    begin (vec1),
    end (vec1),
    back_inserter (vec2),
    [] (const double & x) -> double {
        return x * 10;
    });
This should work. A lambda which does not perform any capturing is convertible to an ordinary function.
it is obviously implemented with a template class for the whole function
Slight aside for proper terminology: std::transform is a function template, not a function. More importantly, in a declaration of the style
template<class InputIterator, class OutputIterator, class Functor>
OutputIterator
transform(InputIterator begin, InputIterator end, OutputIterator out, Functor f);
the template parameters InputIterator, OutputIterator and Functor are not required to be class types. Consider this example:
// function declaration
int increment(int);
int array[] = { 0, 1, 2, 3, 4 };
transform(std::begin(array), std::end(array), std::begin(array), increment);
Then InputIterator and OutputIterator are deduced to be int* and Functor is int(*)(int), none of which is a class type -- much less a template class, but I digress. And in fact, transform could just as well be declared
template<typename InputIterator, typename OutputIterator, typename Functor>
OutputIterator
transform(InputIterator begin, InputIterator end, OutputIterator out, Functor f);
where the keyword typename is a bit more clear on the nature of the template parameters: they're types, of any nature.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With