C++ 可变参数模板

可变参数列表

C语言中的可变参数列表

#include <iostream>
int main(){
    printf("%d %d %d", 1, 2, 3);
    return 0;
}

​ ***可变参数列表:***接受任意个数的参数,如 printf

int printf(const char* format, ...);

​ 函数定义形参部分带 … 。在 C 语言中,三个点并非必要。

C++中的可变参数列表

形参包

void f(int ...num);

形参包: … 与形参名结合便是形参包。形参包可接受任意多个参数。

​ ***范式:***上述的 num 便是范式。… 在形参名之前。

void f(int ...num) {
    int arr[] = {num...};
    //假设传了五个参数,则展开后为
    //int arr[] = {num1, num2, num3, num4, num5};
}

​ ***形参包展开:***参数列表中创建的形参包在后续使用必须展开。… 在范式后即为形参包展开。只展开 … 之前的语句,语句必须带范式形参。展开后的语句以逗号隔开。

可变参数模板

类型形参包

template<typename ...T>

​ ***类型形参包:***与形参包类似,… 后带类型模板便是类型形参包。

template<typename ...T>
std::common_type_t<T...> Add(T ...num) {
    /*...*/
}
/*
std::common_type_t<T...>:自动适配尖括号中类型形参包的公共类型。

假设调用为:Add(1.2,3,5.5f,'\0',2ULL):

std::common_type_t<T...>展开后为:
std::common_type_t<double, int, float, char, unsign long long>

Add(T ...num)展开后为:
Add(double num1, int num2, float num3, char num4, unsign long long num5)
*/

​ ***类型形参包展开:***与形参包展开类似,… 在类型名后便是类型形参包展开。

***总结:***三个点在变量名或模板类型名前是创建形参包,三个点在变量名或模板类型名后是展开形参包。

形参包后续类型形参

#include <numeric>
template<typename ...Args, typename RT = std::common_type_t<Args...>>
RT Add(const Args& ...nums) {
	RT temp[] = { nums... };
	return std::accumulate(std::begin(temp), std::end(temp), RT{ 0 });
}
//std::accumulate 通过迭代器求和
//std::accumulate(起始迭代器, 终止迭代器, 求和结果变量)

​ 后续类型形参无法手动指定,只能通过缺省类型进行指定或推导。

推导指引(C++17)

​ 推导指引只作用于类型模板。

template<typename T>
struct test {
private:
	T a;
public:
	test(T n) :a{ n } {}
	void type() {
		std::cout << typeid(a).name() << std::endl;
	}
};
//推导指引,将int类型推导为double类型后调用模板
test(int)->test<double>;

利用可变参数模板进行推导指引

//模板A,定义结构体array
template<typename Ty, std::size_t size>
struct array {
	Ty arr[size];
};
//模板B,用于推导指引
template<typename T, typename ...Args>
array(T, Args...) -> array<T, sizeof... (Args) + 1>;
//sizeof...(形参包):形参包参数个数

​ 如果没有模板B,多参数创建 array 必须指定模板类型。

array<int,5> a{ 1,2,3,4,5 };
array a{ 1,2,3,4,5 };//没有模板B则编译不通过,编译器无法自行推导

相关推荐

  1. C++ 可变参数模板

    2024-05-09 14:36:11       38 阅读
  2. C++开发基础——可变参数可变参数模板

    2024-05-09 14:36:11       36 阅读
  3. c++ move,可变参数模板,折叠表达式,...

    2024-05-09 14:36:11       53 阅读
  4. C++可变参数模板中的省略号

    2024-05-09 14:36:11       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-09 14:36:11       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-09 14:36:11       101 阅读
  3. 在Django里面运行非项目文件

    2024-05-09 14:36:11       82 阅读
  4. Python语言-面向对象

    2024-05-09 14:36:11       91 阅读

热门阅读

  1. 网闸与防火墙的区别

    2024-05-09 14:36:11       35 阅读
  2. 本地加载hugging face模型:Bert

    2024-05-09 14:36:11       37 阅读
  3. 【Excel VBA】在 Excel VBA 中使用 For 循环全面指南

    2024-05-09 14:36:11       30 阅读
  4. 神经网络和深度学习之间有什么区别

    2024-05-09 14:36:11       29 阅读
  5. React 第二十七章 Hook useMemo

    2024-05-09 14:36:11       37 阅读
  6. Spring AI

    Spring AI

    2024-05-09 14:36:11      30 阅读
  7. Spring IoC&DI—DI详解

    2024-05-09 14:36:11       35 阅读
  8. 分布式数据库有哪几种

    2024-05-09 14:36:11       31 阅读
  9. FFmpeg压缩视频大小

    2024-05-09 14:36:11       36 阅读