C++17尝鲜:类模板中的模板参数自动推导
目录
模板参数自动推导
示例
自定义类模板中的应用
Automatic deduction guides(自动推断向导)
模板参数自动推导
在C++17之前,类模板构造器的模板参数是不能像函数模板的模板参数那样被自动推导的,比如我们无法写
std::pair a{1, "a"s}; // C++17
而只能写
std::pair<int, string> a{1, "a"s}; // C++14
为了弥补这一缺陷,标准库为我们提供了 std::make_pair 函数,通过函数模板的模板参数自动推导的功能,
免去我们在构造 pair 时写模板参数的麻烦。
auto a = std::make_pair(1, "a"s); // C++14
// 相当于
// std::pair<int, string> a = std::make_pair<int, string>(1, string("a"));
// 这里编译器根据 std::make_pair 所带参数的类型,自动推导出了函数模板的参数。
这个解决方案其实并不太理想,这是因为:
- 我们需要记住 make_pair, make_tuple 这类用于构造模板类的惯用法。
- 有些 make_XXX 函数在功能上并不等价于类模板的构造器,比如 make_shared 等等。
在C++17中,这个问题得到了解决,类模板构造器的模板参数同样能够被自动推导
std::pair a{1, "a"s}; // C++17
// 相当于
// std::pair<int, string> a{1, "a"s};
// 和函数模板一样,这里编译器根据 std::pair 构造器所带参数类型,自动推导出了构造器模板的参数。
由此我们不再需要 std::make_pair 之类的辅助函数了。
示例
#include <iostream>
#include <vector>
#include <functional>
#include <string>
#include <map>
#include <algorithm>
using namespace std;int main()
{vector a = {1, 2, 3}; // C++17
// vector<int> a = {1, 2, 3}; // C++14function f = [](int a){return a + 1;}; // C++17
// function<int(int)> f = [](int a){return a + 1;}; // C++14tuple t{1, 2,5, "a"s}; // C++17
// tuple<int, double, string> t{1, 2,5, "a"s}; // C++14
// auto t = make_tuple(1, 2,5, "a"s); // C++14sort(a.begin(), a.end(), greater{}); // C++17
// sort(a.begin(), a.end(), greater<>{}); // C++14
// sort(a.begin(), a.end(), greater<int>{}); // C++11// map m = {{1, "a"s}, {2, "b"s}}; // {1, "a"s} 这种使用大括号的初始化列表没有类型// 所以编译器无法自动推导 map 类模板的参数类型map m = {pair{1, "a"s}, {2, "b"s}}; // C++17
// map<int, string> m = {{1, "a"s}, {2, "b"s}}; // C++14
}
自定义类模板中的应用
template<typename T>
struct Container
{Container(T* ptr) {} // 构造器 1Container(T& v) {} // 构造器 2Container(T const& v) {} // 构造器 3template<typename D>Container(T* ptr, D& deleter) {} // 构造器 4
};struct Deleter {};int main()
{Container c{(int*)0}; // 调用构造器 1int x; Container c2{x}; // 调用构造器 2Container c3{0}; // 调用构造器 3Deleter d;Container c4{(int*)0, d}; // 调用构造器 4
// 以上编译器自动推导的结果都是 Container<int>
}
Automatic deduction guides(自动推断向导)
有些情况下,编译器无法对类模板的参数做出自动推导,比如下面这种模板参数类型是个嵌套类型的情况。
此时我们需要添加自动推断向导来帮助编译器来进行自动推导。
自动推断向导形式如下:
类模板名(参数列表) -> 类模板id
template<typename T>
struct Traits { using type = T; };template<typename T>
struct Container
{// 参数类型是嵌套类型,无法进行自动推导Container(typename Traits<T>::type v) {}
};// 自动推断向导
template<typename T>
Container(T) -> Container<T>;int main()
{Container c(0); // 编译器自动推导的结果是 Container<int>
}
本文转自:https://www.cnblogs.com/zwvista/p/7748363.html
C++17尝鲜:类模板中的模板参数自动推导相关推荐
- C++类模板中的模板函数
在C++中类模板中可以嵌套函数模板,但是在使用时候有些注意事项如下: 一.如果类模板中参数为template<typename T>,在函数模板中,函数的不同模板名字是可以重载的,如tem ...
- template模板中插入自定义参数
辅助方法(解决模板不能访问全局对象的问题) 使用 template.helper(name, callback) 注册公用辅助方法,例如一个访问全局变量jQuery的方法: template.help ...
- C++模板中的函数式参数
前面我们提到过,模板类至少有一个类参数,但是可以有多个参数,这些参数中可以存在非类类型的参数,例如系统内建的普通数据类型参数或程序自定义的数据类型参数,我们将这种非类类型的参数称之为函数式参数. #i ...
- 在Twig模板中获取 request参数
为什么80%的码农都做不了架构师?>>> app.request.server.get('HTTP_X_REQUESTED_WITH') 就是 $_SERVER['HTTP_X ...
- 3、play中的模板引擎
1.模板格式 Play默认的模板引擎是一种基于scala的安全模板引擎,尽管模板引擎使用Scala作为表达式语言,但是非常简单易学.参数类型使用后缀语法指定(例如: id:Long),泛型类型是使用[ ...
- C++中的模板及其使用
一.什么是模板 模板是C++中自动生成代码的技术,例如我们在C++若想实现一个函数的形参可以是多种数据类型就必须使用重载,模板则可以更加简单方便地实现这一点. 二.为什么使用模板 假1如我们想实现一个 ...
- 类模板与函数模板区别
类模板与函数模板区别主要有两点 类模板没有自动类型推导的使用方式 类模板在模板参数列表中可以有默认参数 测试代码 #include <iostream> #include <stri ...
- 模板 (函数模板语法 ,类模板与函数模板的区别,:函数模板案例,普通函数与函数模板的区别,普通函数与函数模板调用规则,模板的局限性,类模板分文件编写.cpp,Person.hpp,类模板与友元)
**01:函数模板语法: #include<iostream> using namespace std;//交换两个整型函数 void swapInt(int &a ,int &a ...
- Java导出数据到Word模板中
Java导出数据到Word模板. 前言 网上的方案 需求介绍 模板 简介 使用体验 poi-tl Freemarker 操作步骤 总结 前言 相信很多人都会遇到Java导出的业务,Java导出主要有导 ...
最新文章
- vc++ 6.0下Glut的配置 及 Glut 框架介绍
- MyEclipse+Tomcat+MAVEN+SVN项目完整环境搭建
- sql注入之order by猜列数问题
- ajax请求的步骤,ajax请求的五个步骤
- Hadoop的NameNode与SecondaryNameNode,DataNode
- 实录 | 平安人寿资深算法工程师姚晓远:对话生成模型的探析与创新
- LeetCode 257. 二叉树的所有路径(DFS)
- JavaWEB/JSP 中简单的验证码 springMVC
- 转)VCSA 6.5重启无法访问,报错“503 Service Unavailable”的解决方法
- ​不容错过的 13 个 JavaScript 实用技巧!
- 40线性映射07——线性变换的矩阵表示、线性变换与基的关系、线性变换坐标间的关系、线性变换在不同基下矩阵之间的关系、相似矩阵
- linux 命令汇总(搜索、fdfs、常用命令),虚拟机dump文件
- 基于 Apache APISIX,爱奇艺 API 网关的更新与落地实践
- Holy Grail 圣杯布局详解
- 南京大学计算机学类,并未开放计算机专业:南京大学2020年强基计划政策分析...
- Chrome 神器面世!谷歌学术搜文章,代码链接自动展示
- 计算机网络 - 传输层
- “一路向南,dream it possible”之旅--骑行从北京到成都(一)
- c++ 从入门到放弃
- dya50 javascript
热门文章
- 干货总结:SPI总线详细要点
- 从单片机工程师的角度看嵌入式Linux
- c语言教改课程项目,C语言程序设计课程的教学改革.pdf
- 树莓派4b上部署yolov3和v3-tiny记录带截图
- redis强一致性_分布式架构一定要有Redis吗?Redis的常见问题我都帮你解答了
- linux远程升级运行程序,运用RedHat的Kickstart升级Linux系统方法
- mysql 5.6 使用ssl_MySQL 5.6--------SSL连接最佳实战
- python2.x和3.x的区别 print_Python2.x和Python3.x的区别
- mysql 定时器概念_MySQL 定时器
- iphone静音键失灵_知否 | 为何大部分安卓机 都不学iPhone加入静音键?