1. 可变参数模板
可变参数模板是 C++11 引入的,允许模板接受任意数量的模板参数,使用参数包来表示n(n>=0)个模板参数。
cpp
模板声明 template<typename... Args>
参数包展开 Args... args
求参数的个数 sizeof...
1.1基本可变参数模板加左折叠
cpp
template <typename... Args>
void print_fold(Args... args)
{
((std::cout << args << " "), ...);
std::cout << std::endl;
}
main---> printAll(1, 2.5, "hello", 'a');
1.2递归展开
cpp
// 递归展开
template<typename T, typename... Args>
void print(T first, Args... args) {
std::cout << first << " ";
print(args...); // 递归调用
}
// 终止递归的函数
void print() {
std::cout << "结束递归" << std::endl;
}
main---> print(1, 2.5, "hello", 'aaa'); // 递归展开
其中 args...表示递归处理除第一个参数外的剩余参数。
内存布局
参数包在内存中的表示:
+----------+----------+------------+----------+
| int | double | const char*| char |
| 1 | 2.5 | "hello" | 'aaa' |
+----------+----------+------------+----------+
↓ ↓ ↓ ↓
Args[0] Args[1] Args[2] Args[3]
2. 折叠表达式 (C++17)
口诀: "有&就是 &,全 && 才是 &&。
左/右折叠:
cpp
template <typename... Args>
void print_fold(Args... args){
(...,(std::cout << args << " "));//左
((std::cout << args << " "), ...);//右
}
对逗号操作符来说,左/右折叠的求值顺序是一样的 ,所以无论用 (..., 表达式) 还是 (表达式, ...),输出顺序都正确。
3. 泛型 Lambda (C++14)
lambda 本身不能直接是模板(C++20 之前。允许在 Lambda 表达式中使用 auto 作为参数类型,使得 Lambda 成为模板函数对象。
[capture-list] (parameters) -> return-type { body }
↑ ↑ ↑ ↑
捕获列表 参数列表(必须) 返回类型 函数体
cpp
//basic
auto func=[](int a,int b)->int{
return a+b;
}
//C++14
auto print_fold_lambda = [](auto &&...args) -> void
{
((std::cout << args << " "), ...);
std::cout << std::endl;
};
一个小样例:获取用户输入的一串数据,中的整形数据。stoi()会过滤非string类型数据。
