2021-11-22 21:57:21
C++14的泛型lambda通过auto关键字声明参数类型,使lambda表达式能够接受任意类型的参数,编译器根据实际调用类型生成模板化的operator()实现。
泛型lambda的核心机制auto参数声明:参数类型由调用时的实际类型推导决定,例如:
auto func = [](auto x) { return x + x; };该lambda可处理int、double或支持+操作的字符串类型。
编译器生成模板类:泛型lambda本质是编译器生成的带模板operator()的类。例如:
struct { template<typename T> auto operator()(T x) const { return x + x; }};每次调用不同类型时,会实例化对应的模板函数。

通用容器遍历对vector<int>和list<double>执行相同操作:
std::vector<int> v = {1, 2, 3};std::list<double> l = {1.5, 2.5, 3.5};std::for_each(v.begin(), v.end(), [](auto& x) { std::cout << x * 2 << " "; });std::for_each(l.begin(), l.end(), [](auto& x) { std::cout << x * 2 << " "; });多类型参数操作参数类型可不同,但需支持操作:
auto add = [](auto a, auto b) { return a + b; };通用逻辑封装
遍历容器并统一处理元素
编写通用的比较逻辑(如排序条件)
构建转换或过滤函数(如类型转换、条件筛选)

无法显式指定模板参数泛型lambda不支持类似func<int>(5)的调用,参数类型必须由调用时推导。
代码膨胀风险每个不同类型调用会生成独立的模板实例,复杂lambda可能导致二进制体积增大。
调试信息复杂模板错误可能引发冗长的编译错误,需结合编译器工具定位问题。
多auto参数的灵活性参数类型可不同,但需满足操作要求(如+、*等运算符支持)。
明确返回类型使用-> decltype(...)指定返回类型:
auto func = [](auto x) -> decltype(x + x) { return x + x; };SFINAE场景在模板元编程中,decltype可辅助类型推导或条件判断。
基础泛型lambda
auto square = [](auto x) { return x * x; };std::cout << square(5); // 输出25(int)std::cout << square(5.0); // 输出25.0(double)多类型参数操作
auto concat = [](auto a, auto b) { return a + b; };std::string s = concat("Hello, ", "world!"); // 字符串拼接int i = concat(1, 2); // 整数相加STL算法中的通用逻辑
std::vector<std::string> names = {"Alice", "Bob"};std::for_each(names.begin(), names.end(), [](auto& name) { std::transform(name.begin(), name.end(), name.begin(), ::toupper);});
通过合理使用泛型lambda,可显著提升C++14代码的通用性和简洁性,尤其在标准库算法和回调逻辑中效果显著。