c++ - 如何在 C++ 中使用可变参数泛型 lambda 计算总和?

标签 c++ generics lambda c++14 variadic

我想编写一个如下所示的通用求和函数,但不是使用模板语法,而是使用 lambda 语法:

template<typename T>
auto Sum(T lastSummand)
{
    return lastSummand;
}

template<typename T, typename... Ts>
auto Sum(T firstSummand, Ts... restSummands)
{
    return firstSummand + Sum(restSummands...);
}

因为通用 lambda 被映射到模板,所以应该可以执行以下操作:

auto sum = [](auto firstSummand, auto... restSummands) { ... };

但我无法弄清楚如何使用 lambda 进行递归。在此和其他位置进行搜索并没有取得太多进展。

最佳答案

在 C++14 中,您实际上不需要递归来使用泛型 lambda 执行此操作。
例如,您可以这样做:

#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;
}

返回类型由给定包的 std::common_type_t 给出。
代码的其余部分包含等待折叠表达式时通常使用的常见模式。

在 C++17 中它将变成:

#include<iostream>

int main() {
    auto l = [](auto... values) { return (values + ...); };
    auto v = l(0, 0., 5, 4.2);
    std::cout << v << std::endl;
}

查看 wandbox .

如果您想即时验证给定参数是否都是算术类型,您可以使用 bool 技巧,如下所示:

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;
};

关于c++ - 如何在 C++ 中使用可变参数泛型 lambda 计算总和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41409637/

相关文章:

c++ - 如何使用正则表达式匹配不包含特殊字符(&、\、<、>、|、)的字符串,除非它们以反斜杠开头

java - 将 lambda 作为具有泛型类型的参数传递 - java 8

c++ find_if lambda

c++ - 如何在 C++ 中向 MFC 项目添加另一个 gui

c++ - Fortran 77 转换为 C++

c++ - 我写了一个程序来显示一个数组的内容,但它显示的是它的地址

java - 如何使用 Jackson 反序列化泛型类?

c# - 理解泛型与继承类的结合

c# - 如何按字典值对对象列表进行排序?

c# - 如何在 .net core ef 上应用上述关系的 thenInclude 条件?