I wanted to write a generic sum function like the following one but not in template syntax but in lambda syntax:
template<typename T>
auto Sum(T lastSummand)
{
return lastSummand;
}
template<typename T, typename... Ts>
auto Sum(T firstSummand, Ts... restSummands)
{
return firstSummand + Sum(restSummands...);
}
Because generic lambdas are mapped to templates it should be possible to do something like:
auto sum = [](auto firstSummand, auto... restSummands) { ... };
But I cannot figure out how to do the recursion using lambdas. Searching in this and other locations did not bring forward much.
In C++14 you don't actually need recursion to do that with generic lambdas.
As an example, you can do this:
#include<type_traits>
#include<iostream>
int main() {
auto l = [](auto... values) {
std::common_type_t<decltype(values)...> ret = {};
decltype(ret) _[] = { (ret += values)... };
(void)_;
return ret;
};
auto v = l(0, 0., 5, 4.2);
std::cout << v << std::endl;
}
Return type is given by the std::common_type_t
of the given pack.
The rest of the code contains the common pattern usually used while waiting for fold expressions.
In C++17 it will become:
#include<iostream>
int main() {
auto l = [](auto... values) { return (values + ...); };
auto v = l(0, 0., 5, 4.2);
std::cout << v << std::endl;
}
See it on wandbox.
If you want to verify on the fly that given parameters are all of arithmetic types, you can use the bool trick as it follows:
auto l = [](auto... values) {
static_assert(
std::is_same<
std::integer_sequence<bool, true, std::is_arithmetic<decltype(values)>::value...>,
std::integer_sequence<bool, std::is_arithmetic<decltype(values)>::value..., true>
>::value, "!"
);
std::common_type_t<decltype(values)...> ret = {};
decltype(ret) _[] = { (ret += values)... };
(void)_;
return ret;
};