📜  C++ 14中的广义Lambda表达式(1)

📅  最后修改于: 2023-12-03 15:29:49.085000             🧑  作者: Mango

C++ 14中的广义Lambda表达式

在C++ 11中,引入了Lambda表达式,它为程序员提供了定义匿名函数的一种方式。但是Lambda表达式的使用有着一些限制,例如无法捕获变长参数列表等。在C++ 14中,引入了广义Lambda表达式,它可以解决这些限制,扩展了Lambda表达式的功能。

广义Lambda表达式的语法

广义Lambda表达式的语法与Lambda表达式类似,只是在参数列表中加入了auto关键字。例如:

auto glambda = [](auto a, auto&& b) { return a < b; };

上述代码定义了一个广义Lambda表达式,它接受两个参数a和b,这两个参数可以是任意类型。

广义Lambda表达式的应用

广义Lambda表达式可以应用于很多场景中,以下是几个例子:

排序

使用广义Lambda表达式可以轻松实现一个通用的排序函数,例如:

template<typename T, typename R = std::less<>>
void sort(std::vector<T>& v, R&& r = R{}) {
    std::sort(v.begin(), v.end(), [=](auto&& a, auto&& b) { return r(a, b); });
}

std::vector<int> v = { 1, 3, 2, 5, 4 };
sort(v);
for (auto i : v) {
    std::cout << i << " ";
}

上述代码中,sort函数使用广义Lambda表达式定义了排序规则,可以让用户选择升序或降序排序。

变长参数

Lambda表达式无法直接处理变长参数,但是使用广义Lambda表达式可以轻松解决这个问题。例如:

auto print = [](auto&&... args) {
    ((std::cout << args << " "), ...);
};

print(1, 2.0, "3");

上述代码中,print函数使用广义Lambda表达式接受任意数量的参数,并将它们输出到标准输出流。

递归Lambda

使用广义Lambda表达式可以更方便地实现递归Lambda函数。例如:

auto factorial = [](auto&& self, int n) -> int {
    if (n == 0) {
        return 1;
    }
    else {
        return n * self(self, n - 1);
    }
};

std::cout << factorial(factorial, 5) << std::endl;

上述代码中,factorial函数是一个递归Lambda函数,使用广义Lambda表达式使得递归调用变得简单。

总结

广义Lambda表达式是C++ 14中的一个重要特性,它大大扩展了Lambda表达式的功能,提高了代码的可读性和灵活性。但是需要注意的是,过度使用广义Lambda表达式也会导致代码变得难以理解,所以在使用广义Lambda表达式时需要权衡利弊。