[TOC]

C++可变参数模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void f(){}
//函数出口,变参本质上像递归,最后没有参数时执行f(),所以需要出口

template<class T, class...Args>
//变参模板格式class...Args,包括后面的Args...args
//想要一个一个操作参数则需 class T——T t
void f(T t, Args...args)
{
std::cout<< t <<"---"<<sizeof...(args)<<'\n';
//t为输入的第一个参数(sizeof...查看参数个数)
f(args...); //剩下的参数递归调用,最后没参数调用出口函数f()
}

int main()
{
f(1,"%%&*$",2.3);
return 0;
}

C++可变参数模板本质上像递归,所以调用到最后无参,需要出口函数。

值得注意的是模板函数需要实例化才能被调用,如果想用if语句代替出口函数,下面是一个错误的用法(注释有正解):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<class T, class...Args>    
void f(T t, Args...args)
{
std::cout<< t <<"---"<<sizeof...(args)<<'\n';
//t为第一个参数,会实例化出T的类型(sizeof...查看参数个数)
if(sizeof...(args) > 0)
//if编译时还会显示出不符合条件的分支,会产生f()
//而f()没有参数模板无法实例化,所以会报无匹配f()
//可以使用if constexpr,编译时去掉不符合条件的分支!
//正确用法为if constexpr(sizeof...(args) > 0)
{
f(args...);
}

}

另外,可变参模板也可传函数(相当于函数指针做变量):

1
2
3
4
5
6
7
8
9
10
11
12
#include <string>
template<class F, class...Args>
auto call(F fuc, Args...args)
{
fuc(args...);
//此例无返回值
}

int main()
{
call([](int a, std::string str){std::cout<<a<<" "<<str<<std::endl;}, 5, "gyduebc");
}

用户自定义字面量

一定要用**_xx,不用下划线的是系统的字面量重载“”函数,用户自定义的一定要用下划线**,并且形参类型有限制,具体见用户自定义字面量

此处一定要有size_t类型参数,不然会报错(因为没有计数参数时,字符数组指针无法知道字符数组长度,也就无从操作)

字符串自动计算了长度:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
void operator""_q(const char* str, size_t size)
{
std::cout<<str<<" "<<size<<std::endl;
}
int main()
{
"fes1314rwffg"_q;
return 0;
}
//fes1314rwffg 12