开发者

lambda with templates

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 c开发者_如何学Pythonorrect 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜