面试之快速学习c++11-函数模版的默认模版参数,可变模版,tuple

news/2024/11/16 7:19:54/

//学习地址: http://c.biancheng.net/view/3730.html

函数模版的默认模版参数

  1. 在 C++98/03 标准中,类模板可以有默认的模板参数,如下:
template <typename T, typename U = int, U N = 0>
struct TestTemplateStruct {};
  1. 但是不支持函数的默认模版参数, c++11可以了,如下:
template <typename T = int>
void TestTemplateFunc() {T a;cout << "a = " << a << endl;
}
  1. 从上面的例子中可以看出,当所有模板参数都有默认参数时,函数模板的调用如同一个普通函数。但对于类模板而言,哪怕所有参数都有默认参数,在使用时也必须在模板名后跟随<>来实例化。
  2. 除了上面提到的部分之外,函数模板的默认模板参数在使用规则上和其他的默认参数也有一些不同,它没有必须写在参数表最后的限制。甚至于,根据实际场景中函数模板被调用的情形,[编译器还可以自行推导出部分模板参数的类型]
  3. 这意味着,当默认模板参数和编译器自行推导出模板参数类型的能力一起结合使用时,代码的书写将变得异常灵活。我们可以指定函数中的一部分模板参数采用默认参数,而另一部分使用自动推导,比如下面的例子:

template <typename R = int, typename U>
R TestTemplateWithCompiler(U val)
{return val;
}void TestTemplateWithCompiler1() {TestTemplateWithCompiler(0);TestTemplateWithCompiler<int , char>(0);TestTemplateWithCompiler<int>(1);
}
  1. 简而言之,就是只要编译期间没问题,那么就没问题

C++11新标准-可变模板参数(variadic templates)

  1. 先聊聊可变参数
void mutableParamsFunc(int count, ...) {va_list params;va_start(params, count);for (int i = 0; i < count; ++i) {int param = va_arg(params, int);cout << "param = " << param << endl;}va_end(params);
}
  1. test :mutableParamsFunc(3, 1 , 2, 3);
    注意如果数量大于可变参数数量时,输出结果会异常,如mutableParamsFunc(4, 1 , 2, 3);
 param = 1param = 2param = 3param = -88828182
  1. 可变参数可能不都是一个数据类型,他们可能存在多个数据类型,比如:
void mutableParamsFunc1(int count, ...) {va_list params;va_start(params, count);for (int i = 0; i < count; ++i) {int int_param = va_arg(params, int);char* char_param = va_arg(params, char*);cout << "int_param = " << int_param << endl;cout << "char_param = " << char_param << endl;}va_end(params);
}
  1. 可变参数函数模版,解包的两种方法,第一种递归解包
//递归出口
void mutableParamsFunc2() {cout << " mutableParamsFunc2 end" << endl;
}
template<typename T, typename... args>
void mutableParamsFunc2(T argc, args... argv) {cout << argc << endl;mutableParamsFunc2(argv...);
}

5.第二种方式,非递归

template<typename T>
void handleMutableParamsFunc3(T t) {cout << t << endl;
}template<typename... args>
void mutableParamsFunc3(args... argv) {int arr[] = {(handleMutableParamsFunc3(argv) , 0)...};
}

tuple

  1. 使用之前要引入
#include<tuple>using std::tuple;
  1. 构造函数
 1) 默认构造函数constexpr tuple();2) 拷贝构造函数tuple (const tuple& tpl);3) 移动构造函数tuple (tuple&& tpl);4) 隐式类型转换构造函数template <class... UTypes>tuple (const tuple<UTypes...>& tpl); //左值方式template <class... UTypes>tuple (tuple<UTypes...>&& tpl);      //右值方式5) 支持初始化列表的构造函数explicit tuple (const Types&... elems);  //左值方式template <class... UTypes>explicit tuple (UTypes&&... elems);  //右值方式6) 将pair对象转换为tuple对象template <class U1, class U2>tuple (const pair<U1,U2>& pr);       //左值方式template <class U1, class U2>tuple (pair<U1,U2>&& pr);            //右值方式
void tupleTest() {std::tuple<int, char> first(1, '1');std::tuple<int, char> second(make_tuple(2, '2'));auto third = make_tuple(3,'3'); //很舒服,不需要指明类型
}
  1. 常用函数
void tupleTest1() {std::tuple<int, char> first(1, '1');std::tuple<int, char> second(make_tuple(2, '2'));auto third = make_tuple(3,'3');auto four = make_tuple("444", 4);//1. swap 注意要是一个类型//first.swap(four); //报错Non-const lvalue reference to type 'tuple<int, char>' cannot bind to a value of unrelated type 'tuple<const char *, int>'first.swap(second);//2. 返回对象 get<num>()cout << "get first 2 objecy = " << get<1>(first) << endl;//3. 返回size tuple_size<type>::value;cout<< "return first tuple size = " << std::tuple_size<decltype(first)>::value << endl;//4. 返回tie(args...) = 功能是将 tup 内存储的元素逐一赋值给 args... 指定的左值变量。int num;std::string str;std::tie(num,str) = second;cout<< "return second 1 =  " << num << " , 2 = " << str << endl;//5.  将多个 tuple 对象整合成一个tupleauto five = tuple_cat(first, second);}

http://www.ppmy.cn/news/1010183.html

相关文章

【Spring Boot系列】- Spring Boot拦截器

【Spring Boot系列】- Spring Boot拦截器 文章目录 【Spring Boot系列】- Spring Boot拦截器一、概述二、拦截器&#xff08;Interceptor&#xff09;定义步骤2.1 定义拦截器&#xff08;Interceptor&#xff09;2.2 注册拦截器&#xff08;Interceptor&#xff09;2.3 拦截器原…

MFC遍历目录包括子目录下所有文件、特定类型文件

文章目录 用法实现遍历所有文件遍历所有txt文件用法 vector<CString> v; //获取所有文件 GetFilePath(v,L"D:\\test\\"); //文件路径储存在容器里面,遍历容器 for(int i=0

go语言使用chan的小技巧

技巧1&#xff1a;关闭某个chan时&#xff0c;所有读取该chan的协程都会收到通知 注意事项&#xff1a;是直接关闭chan就可以了&#xff0c;不需要向这个协程内压入数据&#xff0c;因为压入数据的话最终还得关闭chan 举例&#xff1a;如果协程A希望协程B在处理完某个事情后自…

yolov8在rknn(rv1109/1126)模型转换、量化移植过程

续&#xff1a;rv1109/1126 rknn 模型量化过程_CodingInCV的博客-CSDN博客 Yolov8简介 yolov8是比较新的目标检测模型&#xff0c;根据论文和开源项目的报告&#xff0c;相对使用比较广泛的yolov5提升还比较明显。 yolov8与yolov5相比&#xff0c;结构上的主要区别是将C3结构…

谈谈网络安全

目录 1.概念 2.发展现状 3.主要问题 1.概念 网络安全是指保护计算机网络和其中的数据免受未经授权访问、损坏、窃取或破坏的过程和技术。网络安全涉及预防和检测潜在的威胁和漏洞&#xff0c;并采取措施保护网络的机密性、完整性和可用性。 网络安全的概念包括以下几个方面&am…

每日一题——两数之和

题目 给出一个整型数组 numbers 和一个目标值 target&#xff0c;请在数组中找出两个加起来等于目标值的数的下标&#xff0c;返回的下标按升序排列。 &#xff08;注&#xff1a;返回的数组下标从1开始算起&#xff0c;保证target一定可以由数组里面2个数字相加得到&#xff0…

C++路线(全网20篇高赞文章总结)

为节省时间&#xff0c;可直接跳转到 --> &#x1f33c;干货 目录 &#x1f33c;前言 &#x1f33c;来源 &#x1f416;现状 &#x1f33c;干货 入门阶段 入门项目 学习顺序 &#x1f409;大二打算 &#x1f33c;前言 来源的20篇博客&#xff0c;视频中&#x…

【C++】二叉搜索树的模拟实现

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;命运给你一个低的起点&#xff0c;是想看你精彩的翻盘&#xff0c;而不是让你自甘堕落&#xff0c;脚下的路虽然难走&#xff0c;但我还能走&#xff0c;比起向阳而生&#xff0c;我更想尝试逆风…