当C ++ 14已经具有通用lambda时,在C ++ 20中引入的模板lambda有什么需求?


99

引入了通用lambda,从而可以编写以下代码:

auto func = [](auto a, auto b){
    return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");

很显然,此通用lambda的func工作方式就像模板化函数func一样。

为什么C ++委员会决定为通用lamda添加模板语法?


5
如果您需要使用与参数或返回类型不同的模板类型怎么办?如果体内需要它怎么办?
一些程序员花花公子

有人告诉我是一个有趣的用例。
Max Langhof

Answers:


115

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允许我们轻松实现这些情况。


2
简洁明了。只需添加一下:第一个(相同类型)可以(auto a, decltype(a) b)在C ++ 14中解决。
塞巴斯蒂安·马赫

13
@SebastianMach差不多。使用该解决方案b是不可推论的,其参数将隐式转换为a替代类型。
Quentin

32

由于您可以在C ++ 20中使用模板化的lambda,因此与SFINAE表达式相比,可以以更简单的方式限制类型:

auto lambda = []<typename T>(std::vector<T> t){};

此lambda仅适用于向量类型。


8
如何consteval与新的语法?一切都很酷,但是我没有任何意义。
StoryTeller-Unslander Monica,

它是关于C ++ 20为lambda表达式添加的内容的更多信息,而不是对问题的答案
Antoine Morrier

24

被C ++ 20接受的建议有一个冗长的动机部分,并带有示例。它的前提是:

作者认为当前定义通用lambda的语法不足的几个关键原因。其要点是,某些可以使用常规功能模板轻松完成的事情需要使用通用Lambda进行很大的跳跃,或者根本无法完成。作者认为Lambda足够有价值,因此C ++应该支持它们以及正常的功能模板。

接下来是很多示例。


21

 与C ++ 17替代方案相比,C ++ 20中引入的针对lambda的新的“熟悉的模板语法”使诸如  for_types 和的结构  for_range可行且可读性更高。

(来源:使用C ++ 20 lambdas进行编译时迭代

在C ++ 14和C ++ 17通用lambda上都可以完成的另一件有趣的事情是直接调用 operator()  通过显式传递模板参数:

C ++ 14:

   auto l = [](auto){ };
   l.template operator()<int>(0);

C ++ 20:

  auto l = []<typename T>(){ };
  l.template operator()<int>();

上面的C ++ 14示例非常无用:operator() 在不给参数命名和使用的情况下,无法引用lambda主体中  提供的类型。 decltype。此外,即使我们可能不需要参数,我们也不得不传递该参数。

C ++ 20示例显示了如何在lambda的主体中轻松访问T,并且现在可以任意地对无效lambda进行模板化。这对于实现上述编译时构造将非常有用

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.