C++11中函数作为模板参数的新传递方式有哪些?
C++11中函数作为模板参数的核心改进
1. 简化函数指针类模板参数的传递与优化支持
C++11优化了函数作为模板参数的推导逻辑,同时对static inline函数的模板参数适配更友好。之前用函数指针作为模板参数时,常需要显式声明指针类型,且编译器可能因无法确定指针指向而抑制内联;现在直接传递static inline函数名即可,编译器能在模板实例化阶段精准绑定函数,更易做内联优化。
示例代码:
#include <iostream> // 接受函数类型模板参数的通用模板 template <typename Func> void execute(Func func) { func(100); } // static inline 目标函数 static inline void log_number(int num) { std::cout << "Number: " << num << std::endl; } int main() { // 直接传递函数名,编译器自动推导模板参数 execute(log_number); return 0; }
2. Lambda表达式替代手动编写Functor
C++11引入的Lambda表达式可以直接作为模板参数传递,无需手动定义重载()运算符的Functor类。Lambda会被编译器隐式转换为匿名Functor类型,且该类型是编译期唯一确定的,模板实例化时能精准匹配,编译器可充分做内联等优化,比传统手动Functor简洁数倍。
示例代码:
#include <iostream> template <typename CalcFunc> int calculate(CalcFunc op, int a, int b) { return op(a, b); } int main() { // 直接传入Lambda作为模板参数,无需额外定义类 int sum = calculate([](int x, int y) { return x + y; }, 15, 25); int product = calculate([](int x, int y) { return x * y; }, 15, 25); std::cout << "Sum: " << sum << ", Product: " << product << std::endl; return 0; }
3. Constexpr函数作为编译期模板参数
C++11新增的constexpr关键字允许函数在编译期求值,其函数地址可作为非类型模板参数直接传递,模板实例化完全在编译期完成,彻底消除运行时开销。这种方式下,编译器能直接将函数逻辑内联到模板实例中,优化程度远高于传统函数指针。
示例代码:
// constexpr函数,编译期可求值 constexpr int double_val(int x) { return x * 2; } // 非类型模板参数为函数指针 template <int (*Func)(int)> int compile_time_apply(int x) { return Func(x); } int main() { // 直接传递constexpr函数名作为模板参数,编译期计算结果 int result = compile_time_apply<double_val>(3); // 编译期得到6 return 0; }
4. 模板实参推导规则增强
C++11改进了模板实参推导逻辑,当传递函数、Lambda或其他可调用对象给模板时,编译器能自动推导模板参数的具体类型,无需显式指定decltype或函数指针类型,大幅简化了代码书写。
比如C++03风格需要显式指定模板参数:
execute<decltype(&log_number)>(&log_number);
而C++11中只需直接写:
execute(log_number);
内容的提问来源于stack exchange,提问作者比尔盖子
相关产品推荐
相关产品推荐

