泛型 Lambda

C++14 引入了泛型 Lambda(Generic Lambdas),允许在 Lambda 表达式中使用自动类型推导,使得 Lambda 表达式可以接受任意类型的参数。这是通过使用 auto 关键字作为参数类型来实现的。

在 C++11 中,Lambda 表达式的参数类型必须明确指定。而 C++14 的泛型 Lambda 则允许我们编写更通用的 Lambda,类似于函数模板,但语法更简洁。

基本语法

[](auto param1, auto param2, ...) 
{ 
    // 函数体 
};

每个使用 auto 的参数都会独立地进行类型推导,类似于函数模板中的每个独立模板参数。

使用场景

完美转发

template<typename T1, typename T2>
auto process(T1&& arg1, T2&& arg2)
{
    return static_cast<int>(std::forward<T1>(arg1))
                   * static_cast<double>(std::forward<T2>(arg2));
}

auto PerfectForward = [](auto&&... args)
{
    return process(std::forward<decltype(args)>(args)...);
};

int main()
{
    cout << PerfectForward(10, 3.14) << endl;
    return 0;
}

输出如下:

31.4

可变参数泛型 Lambda

// 接受任意数量和类型的参数
auto printAll = [](auto&&... args)
{
    (std::cout << ... << args) << std::endl; // C++17 折叠表达式
};

int main()
{
    printAll(1, " hello ", 3.14, '!');
    return 0;
}

输出如下:

1 hello 3.14!

技术细节

泛型 Lambda 实际上会被编译器转换为一个带有模板调用运算符的匿名类。

// 这个泛型 Lambda:
auto lambda = [](auto x) { return x * 2; };

// 大致等价于:
class AnonymousClass 
{
public:
    template<typename T>
    auto operator()(T x) const 
    {
        return x * 2;
    }
};

虽然泛型 Lambda 接受任意类型,但函数体中的操作必须对所有可能的类型有效。例如:

// 这个 Lambda 只有在类型支持 + 操作时才能编译
auto add = [](auto a, auto b) { return a + b; };

// 编译错误:如果传入不支持 + 操作的类型
// add(std::vector<int>{}, std::vector<int>{}); // 错误!

 

posted @ 2026-04-13 16:24  西兰花战士  阅读(2)  评论(0)    收藏  举报