简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
1.前言
本篇目的:理解C++之Args可变参数模板用法。
2.Args可变参数模板介绍
- C++中,Args是一个通用的模板参数,用于表示一个参数包。它可以用于函数模板、类模板以及其他支持模板参数的上下文中。
Args通常用于以下两种情况:
1. **函数模板参数包
:在函数模板中,Args可以表示一个参数包,用于接受任意数量的参数。通过使用参数包展开的方式,可以在函数模板中处理不定数量的参数。
template <typename... Args>
void PrintArgs(Args... args) {
((std::cout << args << " "), ...);
}
Args表示一个参数包,可以接受任意数量的参数。通过折叠表达式(std::cout << args << " "),我们可以依次打印出每个参数。
2. 类模板参数包
:在类模板中,Args可以表示一个参数包,用于接受多个类型参数。通过使用参数包展开的方式,可以在类模板中处理多个类型参数。
template <typename... Args>
class Tuple {
public:
Tuple(Args... args) {
// 构造函数逻辑
}
};
Args表示一个参数包,用于接受多个类型参数。在类模板的构造函数中,我们可以使用参数包来接受多个参数,并在构造函数的逻辑中进行处理。
3.总结:
Args是一个通用的模板参数,用于表示一个参数包。它可以用于函数模板、类模板以及其他支持模板参数的上下文中,用于接受任意数量的参数或多个类型参数。通过使用参数包展开的方式,可以在模板中处理不定数量的参数或多个类型参数。
3.代码实例
1.使用函数指针调用成员函数
#include <iostream>
class MyClass {
public:
void MyFunction(int a, float b) {
std::cout << "a: " << a << ", b: " << b << std::endl;
}
};
int main() {
MyClass obj;
void (MyClass::*member)(int, float) = &MyClass::MyFunction;
(obj.*member)(10, 3.14f);
return 0;
}
定义了一个名为MyClass的类,其中包含一个成员函数MyFunction。然后,我们声明了一个函数指针member,它指向MyFunction函数。最后,我们通过对象指针和函数指针来调用成员函数,传递参数10和3.14f。运行这个程序会输出a: 10, b: 3.14。
2.使用函数参数包传递任意数量的参数
#include <iostream>
template <typename... Args>
void PrintArgs(Args... args) {
std::cout << "Number of arguments: " << sizeof...(args) << std::endl;
std::cout << "Arguments: ";
((std::cout << args << " "), ...);
std::cout << std::endl;
}
int main() {
PrintArgs(10, "Hello", 3.14f);
return 0;
}
定义了一个模板函数PrintArgs,它接受任意数量的参数,并打印出参数的数量和值。我们使用折叠表达式(std::cout << args << " ")来依次打印每个参数。在main函数中,我们调用PrintArgs函数,并传递参数10,"Hello"和3.14f。运行这个程序会输出Number of arguments: 3和Arguments: 10 Hello 3.14。
3.模板函数调用类中的成员函数
#include <iostream>
class TEST {
public:
void print_test(int a, float b) {
std::cout << "a: " << a << ", b: " << b << std::endl;
}
};
//v1.0: 不使用template模板和Args
void call0(TEST* obj, void (TEST::*member)(int a, float b), int x , int y) {
(obj->*member)(std::forward<int>(x), std::forward<int>(y));
}
//v2.0: 使用template模板,但是不使用Args
template <typename... Args>
void call(TEST* obj, void (TEST::*member)(int a, float b), Args... args) {
(obj->*member)(std::forward<Args>(args)...);
}
//v3.0 使用Args变长参数
//obj:表示TEST对象;
//TEST::*member:表示TEST类成员函数
//Args... args: 表示成员函数参数
template <typename... Args>
void call1(TEST* obj, void (TEST::*member)(Args...), Args... args) {
(obj->*member)(std::forward<Args>(args)...);
}
int main() {
/*
obj:表示TEST对象,对应真正的对象:&obj0.
TEST::*member:表示TEST类成员函数,对应真正的函数&TEST::print_test()
Args... args: 表示成员函数参数 ,对应真正的参数11, 0.34.
*/
//v1.0
TEST obj0;
call(&obj0, &TEST::print_test, 11, 0.34);
//v2.0
TEST obj;
call(&obj, &TEST::print_test, 23, 0.11);
//v3.0
TEST obj1;
call1(&obj, &TEST::print_test, 133, 3.14f);
//v4.0
TEST obj2;
void (TEST::*print)(int, float) = &TEST::print_test;
(obj.*print)(100, 4.34);
return 0;
}
定义了一个名为TEST类,其中包含一个成员函数print_test。然后,我们使用模板函数call来调用print_test函数,并传递参数10和3.14f。运行这个程序会输出a: 10, b: 3.14。