//学习地址: http://c.biancheng.net/view/3730.html
函数模版的默认模版参数
- 在 C++98/03 标准中,类模板可以有默认的模板参数,如下:
template <typename T, typename U = int, U N = 0>
struct TestTemplateStruct {};
- 但是不支持函数的默认模版参数, c++11可以了,如下:
template <typename T = int>
void TestTemplateFunc() {T a;cout << "a = " << a << endl;
}
- 从上面的例子中可以看出,当所有模板参数都有默认参数时,函数模板的调用如同一个普通函数。但对于类模板而言,哪怕所有参数都有默认参数,在使用时也必须在模板名后跟随<>来实例化。
- 除了上面提到的部分之外,函数模板的默认模板参数在使用规则上和其他的默认参数也有一些不同,它没有必须写在参数表最后的限制。甚至于,根据实际场景中函数模板被调用的情形,[编译器还可以自行推导出部分模板参数的类型]。
- 这意味着,当默认模板参数和编译器自行推导出模板参数类型的能力一起结合使用时,代码的书写将变得异常灵活。我们可以指定函数中的一部分模板参数采用默认参数,而另一部分使用自动推导,比如下面的例子:
template <typename R = int, typename U>
R TestTemplateWithCompiler(U val)
{return val;
}void TestTemplateWithCompiler1() {TestTemplateWithCompiler(0);TestTemplateWithCompiler<int , char>(0);TestTemplateWithCompiler<int>(1);
}
- 简而言之,就是只要编译期间没问题,那么就没问题
C++11新标准-可变模板参数(variadic templates)
- 先聊聊可变参数
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);
}
- test :mutableParamsFunc(3, 1 , 2, 3);
注意如果数量大于可变参数数量时,输出结果会异常,如mutableParamsFunc(4, 1 , 2, 3);
param = 1param = 2param = 3param = -88828182
- 可变参数可能不都是一个数据类型,他们可能存在多个数据类型,比如:
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);
}
- 可变参数函数模版,解包的两种方法,第一种递归解包
//递归出口
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
- 使用之前要引入
#include<tuple>using std::tuple;
- 构造函数
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'); //很舒服,不需要指明类型
}
- 常用函数
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);}