的c + + 14 引入了通用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添加模板语法?
的c + + 14 引入了通用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添加模板语法?
Answers:
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允许我们轻松实现这些情况。
(auto a, decltype(a) b)
在C ++ 14中解决。
b
是不可推论的,其参数将隐式转换为a
替代类型。
由于您可以在C ++ 20中使用模板化的lambda,因此与SFINAE表达式相比,可以以更简单的方式限制类型:
auto lambda = []<typename T>(std::vector<T> t){};
此lambda仅适用于向量类型。
consteval
与新的语法?一切都很酷,但是我没有任何意义。
被C ++ 20接受的建议有一个冗长的动机部分,并带有示例。它的前提是:
作者认为当前定义通用lambda的语法不足的几个关键原因。其要点是,某些可以使用常规功能模板轻松完成的事情需要使用通用Lambda进行很大的跳跃,或者根本无法完成。作者认为Lambda足够有价值,因此C ++应该支持它们以及正常的功能模板。
接下来是很多示例。
与C ++ 17替代方案相比,C ++ 20中引入的针对lambda的新的“熟悉的模板语法”使诸如
for_types
和的结构for_range
可行且可读性更高。
在C ++ 14和C ++ 17通用lambda上都可以完成的另一件有趣的事情是直接调用 operator()
通过显式传递模板参数:
auto l = [](auto){ };
l.template operator()<int>(0);
auto l = []<typename T>(){ };
l.template operator()<int>();
上面的C ++ 14示例非常无用:operator()
在不给参数命名和使用的情况下,无法引用lambda主体中 提供的类型。 decltype
。此外,即使我们可能不需要参数,我们也不得不传递该参数。
C ++ 20示例显示了如何在lambda的主体中轻松访问T,并且现在可以任意地对无效lambda进行模板化。这对于实现上述编译时构造将非常有用