C++20: 缩写函数模板和约束性Auto

C++20: 缩写函数模板和约束性Auto

作者:BlogUpdater |  时间:2021-02-06 |  浏览:419 |  评论已关闭 条评论

C++20之不懂系列
在C++中声明一个函数模板一直都比较复杂。C++20添加了一种新的方法,使之更简洁,并且与lambda更加一致:缩写函数模板。今天的这篇简短文章,我将展示如何使用此语法并将其应用于C++ 20 Concepts。

缩写函数模板到底是个什么东西?
C++11中引入了lambda表达式,类似于下图这样:

你只能使用参数type_1和type_2来调用此lambda表达式。但是,在类型难以完全确定的情况下(尤其是在使用ranges等功能时),我们也会经常用到lambda。C++14允许你编写使用了auto关键字与任何类型的参数调用的lambda表达式,如下图所示:

现在你可以传递任何类型的参数。C++20的缩写功能模板允许你将这种语法应用于功能模板。
在C++17中,你可能编写了如下这个一个函数模块,它会模拟动物”抓你一下”这个功能,因为它接受一个动物对象的参数,这样你可以用任何类型的动物来调用它,如下图所示:

在C++20中,你可以使用关键字auto来简化代码:

从上面的代码,我们可以感受到C++20版本的代码更加精简,输入的类型更加少了,并且也和C++14的Lambda表达式更加一致。

约束性Auto
上面的函数模板有一个问题:根据声明,我们可以将所有内容传递给它,所以我们可以编写类似下面的代码:

代码可能能够编译通过同时得到意外的结果,或者可能由于模板的内部实现而编译不通过。在理想情况下,我们既要用支持的类型来记录此功能模板的接口,又要使编译器能够在使用不兼容类型实例化声明时给出详细的错误。

C++20为我们提供了帮助解决此问题的概念。如果我们有一些animal对象的概念来定义代表动物的类型应具有的接口,则可以这样使用它:

这是非常冗长和重复的。理想情况下,我们可以像这样在函数参数列表中直接使用概念名称:

但是,此语法已被标准化所拒绝,因为在不知道animal是类型还是Concept的情况下,你无法分辨出这是函数模板还是常规函数。

幸运的是,C++20中包含了此语法的一个版本,该版本再次使用了auto关键字:

这可以检查是否可以代替auto来满足animal的conecpt。因此,如果我们用kitten实例化模板,则将检查animal。这使我们返回了简洁的语法,同时还允许我们约束模板声明。

总结
约束性auto已经被Visual Studio 2019 v16.8的MSVC编译器所支持。
而缩写函数模板最近才在Visual Studio 2019 v16.9 预览版3中被支持。
那么,猿友们:来都来了,就试试呗。
(我写完上面的文字,完全不懂Sy大神在说些啥。)

最后
Microsoft Visual C++团队的博客是我非常喜欢的博客之一,里面有很多关于Visual C++的知识和最新开发进展。大浪淘沙,如果你对Visual C++这门古老的技术还是那么感兴趣,则可以经常去他们那(或者我这)逛逛。
本文来自:《Abbreviated Function Templates and Constrained Auto》

标签:

评论已关闭。