当C++14已经具有泛型lambda时,在C++20中引入的模板lambda需要什么
What is the need of template lambda introduced in C++20 when C++14 already has generic lambda?
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中使用模板lambdas,因此您可以用比SFINAE表达式更简单的方式限制类型:
auto lambda = []<typename T>(std::vector<T> t){};
此lambda仅适用于向量类型。
新的"熟悉的模板语法";对于C++20中引入的lambda使
for_types
和for_range
等构建体变得可行与C++17替代方案相比可读。
(来源:使用C++20 lambdas的编译时迭代)
在C++14和C++17通用lambda上可以完成的另一件有趣的事情是通过显式传递模板参数来直接调用operator()
:C++14:
auto l = [](auto){ };
l.template operator()<int>(0);
C++20(另请参阅cpprreference上对<tparams>
的解释):
auto l = []<typename T>(){ };
l.template operator()<int>();
上面的C++14示例非常无用:如果不给参数一个名称并使用decltype
,就无法在lambda的主体中引用提供给operator()
的类型。此外,我们被迫通过一个论点,即使我们可能不需要它
C++20示例显示了T在lambda的主体中是如何容易访问的,并且现在可以任意模板化null lambda。这对于上述编译时构造的实现将非常有用。
C++20接受的建议有一个很长的动机部分,并附有示例。其前提是:
当前定义的语法有几个关键原因作者认为通用lambdas是不够的。要点是使用普通函数模板可以轻松完成的一些事情要求用普通羊羔肉进行显著的环跳,或者根本做不到。作者认为lambdas很有价值足以让C++像支持正常函数一样支持它们模板。
下面是一些例子。
- 这 4 个 lambda 表达式之间有什么区别?
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- C++:Lambda 函数指针转换的用例是什么?
- Visual C++: MSVC vs. GCC+CLANG: 处理 lambda 捕获类成员变量,正确的方法是什么?
- 引用捕获和在 lambda 中通过引用发送参数有什么区别 (C++)
- 传递 lambda 函数的权衡是什么?
- &&对lambda表达式有什么好处?
- 这个size_t在 lambda 中有什么作用?C++代码
- 关于函数模板中定义的 lambda 闭包类型可以说些什么?
- 这个 lambda 的目的是什么?
- C++ : 在 lambda 表达式中捕获的目的是什么?
- lambda 的默认捕获是什么?
- 将函数的引用和 lambda 表达式作为参数传递时有什么区别?
- 这个函数和 lambda 有什么区别?
- 将 lambda 作为模板参数传递:实际推导出什么类型
- 包含通过引用捕获的 lambda 函数的"variable"的类型是什么?
- 我在 Lambda 上做错了什么
- 如果我在lambda中删除容纳lambda的对象,那会发生什么
- 这个 lambda 的参数是什么类型?
- 内联和constexpr在标头中无捕获lambda有什么区别