跳转到内容

C++ 变参模板

来自代码酷
Admin留言 | 贡献2025年4月28日 (一) 21:28的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

模板:Note

C++变参模板(Variadic Templates)[编辑 | 编辑源代码]

变参模板(Variadic Templates)是C++11引入的一项强大特性,允许模板接受任意数量任意类型的模板参数。它是实现泛型编程和元编程的重要工具,广泛应用于标准库(如`std::tuple`、`std::function`)和现代C++框架中。

基本概念[编辑 | 编辑源代码]

变参模板的核心语法是通过省略号(`...`)声明参数包(Parameter Pack),并在后续展开使用。参数包分为两种:

  • 模板参数包(Template Parameter Pack):在模板声明中接受多个参数。
  • 函数参数包(Function Parameter Pack):在函数参数列表中接受多个参数。

语法示例[编辑 | 编辑源代码]

  
// 模板参数包  
template<typename... Args>  
void foo(Args... args); // 函数参数包

参数包的展开[编辑 | 编辑源代码]

参数包必须通过展开(Expansion)才能使用,常见方式包括:

递归展开[编辑 | 编辑源代码]

通过递归模板函数逐层处理参数包中的每个参数。

  
// 基准情形(终止递归)  
void print() {  
    std::cout << "End\n";  
}  

// 递归展开  
template<typename T, typename... Args>  
void print(T first, Args... args) {  
    std::cout << first << "\n";  
    print(args...); // 递归调用  
}  

int main() {  
    print(1, 2.5, "Hello");  
}

输出

  
1  
2.5  
Hello  
End  

折叠表达式(C++17)[编辑 | 编辑源代码]

简化递归展开的语法,支持一元或二元操作符。

  
template<typename... Args>  
auto sum(Args... args) {  
    return (args + ...); // 折叠表达式  
}  

int main() {  
    std::cout << sum(1, 2, 3, 4); // 输出:10  
}

实际应用案例[编辑 | 编辑源代码]

实现泛型日志函数[编辑 | 编辑源代码]

  
template<typename... Args>  
void log(const char* format, Args... args) {  
    printf(format, args...);  
}  

int main() {  
    log("Value: %d, Name: %s\n", 42, "Alice");  
}

构建元组(std::tuple)[编辑 | 编辑源代码]

变参模板是`std::tuple`的实现基础:

  
template<typename... Types>  
class Tuple;  

// 特化递归定义  
template<typename Head, typename... Tail>  
class Tuple<Head, Tail...> : private Tuple<Tail...> {  
    Head value;  
};  

template<>  
class Tuple<> {}; // 基准情形

高级主题[编辑 | 编辑源代码]

参数包的大小[编辑 | 编辑源代码]

使用`sizeof...(Args)`获取参数包中参数的数量:

  
template<typename... Args>  
void countArgs(Args... args) {  
    std::cout << sizeof...(Args) << "\n";  
}

完美转发参数包[编辑 | 编辑源代码]

结合`std::forward`实现完美转发:

  
template<typename... Args>  
void wrapper(Args&&... args) {  
    some_function(std::forward<Args>(args)...);  
}

总结[编辑 | 编辑源代码]

  • 变参模板通过参数包和展开机制支持任意数量和类型的参数。
  • 递归展开是基础方法,折叠表达式(C++17)提供更简洁的语法。
  • 广泛应用于标准库、日志系统、元编程等场景。

模板:Tip