c++14引入了通用 lambda,使得编写以下内容成为可能:
auto func = [](auto a, auto b){
return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");
很明显,这个通用 lambdafunc
就像模板函数func
一样工作。
为什么 C++ 委员会决定为泛型 lamda 添加模板语法?
c++14引入了通用 lambda,使得编写以下内容成为可能:
auto func = [](auto a, auto b){
return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");
很明显,这个通用 lambdafunc
就像模板函数func
一样工作。
为什么 C++ 委员会决定为泛型 lamda 添加模板语法?
C++14 泛型 lambda 是一种非常酷的方式来生成具有operator ()
如下所示的仿函数:
template <class T, class U>
auto operator()(T t, U u) const;
但不是这样:
template <class T>
auto operator()(T t1, T t2) const; // Same type please
也不是这样:
template <class T, std::size_t N>
auto operator()(std::array<T, N> const &) const; // Only `std::array` please
也不是这样(尽管实际使用起来有点棘手):
template <class T>
auto operator()() const; // No deduction
C++14 lambda 很好,但 C++20 允许我们轻松实现这些情况。
由于您可以在 C++20 中使用模板化 lambda,因此您可以以比 SFINAE 表达式更简单的方式限制您的类型:
auto lambda = []<typename T>(std::vector<T> t){};
此 lambda 仅适用于向量类型。
被 C++20 接受的提案有一个冗长的动机部分,并附有示例。它的前提是这样的:
作者认为当前定义泛型 lambda 的语法不够充分有几个关键原因。它的要点是,使用普通函数模板可以轻松完成的一些事情需要使用通用 lambda 来完成,或者根本无法完成。作者认为 lambda 足够有价值,C++ 应该支持它们和普通的函数模板一样。
以下是相当多的例子。
与 C++17 的替代方案相比,C++20 中引入的用于 lambda 的新“熟悉的模板语法”使得诸如
for_types
和 之类的构造变得可行且更具可读性。for_range
可以在 C++14 和 C++17 通用 lambda 上完成的另一件有趣的事情是 operator()
通过显式传递模板参数直接调用:
C++14:
auto l = [](auto){ };
l.template operator()<int>(0);
C++20(另见<tparams>
关于 cppreference的解释):
auto l = []<typename T>(){ };
l.template operator()<int>();
上面的 C++14 示例非常无用:如果 operator()
不给参数一个名称并使用 decltype
. 此外,即使我们可能不需要它,我们也被迫传递一个参数。
C++20 示例展示了如何在 lambda 的主体中轻松访问 T,并且现在可以任意模板化空值 lambda。这对于实现上述编译时结构将非常有用。