6

我正在尝试实现一个 reduce 函数,但我不知道如何获取 lambda 的返回类型:

template <typename IT, typename F, typename OT = IT>
auto reducef(const IT& input, F func) -> decltype(func(IT::value_type))
{
    decltype(func(typename IT::value_type)) result = {}; 
    return std::accumulate(input.begin(), input.end(), result, func);
}

编译器输出如下:

test.cpp: In function ‘int main(int, char**)’:
test.cpp:37:80: error: no matching function for call to ‘reducef(std::vector<int>&, main(int, char**)::<lambda(const int&, const int&)>)’
test.cpp:37:80: note: candidate is:
test.cpp:22:6: note: template<class IT, class F, class OT> decltype (func(IT:: value_type)) reducef(const IT&, F)
test.cpp:22:6: note:   template argument deduction/substitution failed:
test.cpp: In substitution of ‘template<class IT, class F, class OT> decltype (func(IT:: value_type)) reducef(const IT&, F) [with IT = std::vector<int>; F = main(int, char**)::<lambda(const int&, const int&)>; OT = std::vector<int>]’:
test.cpp:37:80:   required from here
test.cpp:22:6: error: dependent-name ‘IT:: value_type’ is parsed as a non-type, but instantiation yields a type
test.cpp:22:6: note: say ‘typename IT:: value_type’ if a type is meant

扩展用例:

template <typename IT, typename F, typename OT = IT>
OT mapf(const IT& input, F func)
{
    OT output;
    output.resize(input.size());
    std::transform(input.begin(), input.end(), output.begin(), func);
    return output;
}

template <typename IT, typename F, typename OT = IT>
auto reducef(const IT& input, F func) -> decltype(func(IT::value_type))
{
    typename IT::value_type result = {};
    return std::accumulate(input.begin(), input.end(), result, func);
}


int main(int argc, char *argv[])
{
    vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    auto v2 = mapf(v1, [](const int& i) { return i+1;});
    for (const auto& i : v2)
    {     
        cout << i << endl;  
    }   
    cout << reducef(v1, [](const int& i, const int& j) -> int { return i + j; }) << endl;
}            
4

1 回答 1

6

我认为您想将返回类型声明为

decltype(func(std::declval<typename IT::value_type>(),
              std::declval<typename IT::value_type>()))

这是一个完整的测试用例:

#include <algorithm>
#include <utility>
#include <vector>
#include <numeric>

template <typename IT, typename F, typename OT = IT>
auto reducef(const IT& input, F func)
    -> decltype(func(std::declval<typename IT::value_type>(),
                     std::declval<typename IT::value_type>()))
{
    decltype(func(std::declval<typename IT::value_type>(),
                  std::declval<typename IT::value_type>())) result{};
    return std::accumulate(input.begin(), input.end(), result, func);
}

int main()
{
    std::vector<int> values;
    reducef(values, [](int a, int b) { return a + b; });
}
于 2012-11-19T20:34:41.257 回答