简体   繁体   English

C ++ 11中的高阶函数

[英]Higher-order functions in C++11

I'm trying to write a generic fold function using the new anonymous functions available in C++11, here is what I have: 我正在尝试使用C ++ 11中提供的新匿名函数编写泛型折叠函数,这是我所拥有的:

template<typename T>
T foldl(std::function<T(T,T)> f, T initial, std::vector<T> items) {
    T accum = initial;
    for(typename std::vector<T>::iterator it = items.begin(); it != items.end(); ++it) {
        accum = f(accum, (*it));
    }
    return accum;
}

The following attempt to use it: 以下尝试使用它:

std::vector<int> arr;
arr.assign(8, 2);
foldl([] (int x, int y) -> int { return x * y; }, 1, arr);

causes an error: 导致错误:

main.cpp:44:61: error: no matching function for call to 'foldl(main(int, char**)::<lambda(int, int)>, int, std::vector<int>&)'
main.cpp:44:61: note: candidate is:
main.cpp:20:3: note: template<class T> T foldl(std::function<T(T, T)>, T, std::vector<T>)
main.cpp:20:3: note:   template argument deduction/substitution failed:
main.cpp:44:61: note:   'main(int, char**)::<lambda(int, int)>' is not derived from 'std::function<T(T, T)>'

It seems to me that using std::function is not the right way to go about defining the type of f . 在我看来,使用std::function不是定义f类型的正确方法。 How can I correct this? 我怎么能纠正这个?

Your code is not very generic. 您的代码不是很通用。 There is no need to require a function , vector , or anything of the kind. 不需要functionvector或任何类型的东西。 And generally, in C++, functions would go at the end of the argument list (especially important for lambdas, as they can be big). 通常,在C ++中,函数将位于参数列表的末尾(对于lambdas尤其重要,因为它们可能很大)。

So it would be better (ie: more standard) to write this as this: 所以写这个会更好(即:更标准):

template<typename Range, typename Accum>
typename Range::value_type foldl(const Range &items, const typename Range::value_type &initial, Accum f)
{
    typename Range::value_type accum = initial;
    for(const auto &val : items) {
        accum = f(accum, val);
    }

    return accum;
}

Or you could just use std::accumulate which does the exact same thing . 或者你可以使用std::accumulate来完成同样的事情

I'm not certain why this template is failing, but switching over to using a template parameter for the function instead of std::function<> seems to work wonderfully. 我不确定为什么这个模板失败,但切换到使用函数的模板参数而不是std::function<>似乎工作得非常好。

template<typename T, typename F>
T foldl(F f, T initial, std::vector<T> items) {

If you simply convert it to an std::function first, and then use that, it will work: 如果您只是先将其转换为std::function ,然后使用它,它将起作用:

std::vector<int> arr;
arr.assign(8, 2);
std::function<int(int,int)> f = [] (int x, int y) -> int { return x * y; };
foldl(f, 1, arr);

The problem is that lambda is a different type than std::function . 问题是lambda是一个与std::function不同的类型。 Each lambda is a separate type. 每个lambda都是一个单独的类型。 Although a lambda (and all other function objects) is convertible to a std::function with appropriate type parameter, the compiler has no idea what template argument for T would make it convertible. 虽然lambda(以及所有其他函数对象)可以转换为具有适当类型参数的std::function ,但编译器不知道T哪个模板参数会使其可转换。 (We happen to know that T = int would work, but there is no general way to figure it out.) So it cannot compile it. (我们碰巧知道T = int会起作用,但是没有通用的方法来解决它。)所以它无法编译它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM