I'm trying to implement a reduce function but I don't know how to take the return type of the 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);
}
Compiler output is the following:
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
Extended use case:
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;
}
I think you want to declare you return type as something like
decltype(func(std::declval<typename IT::value_type>(),
std::declval<typename IT::value_type>()))
Here is a complete testcase:
#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; });
}
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