C++:函数模板非类型参数能否自动类型推导?
非类型模板参数的自动推导问题解答
好问题!在C++17及以后的标准里,非类型模板参数确实支持自动推导,但得结合具体的模板结构来看——咱们就拿你给出的代码来拆解说明:
你的模板代码分析
先看你定义的func_a模板:
template<typename T, T val> void func_a(void) { std::cout << val << std::endl; }
你原来的调用方式是func_a<uint32_t, 42u>();,需要显式指定类型参数uint32_t和非类型参数42u。但在C++17及更高版本中,你完全可以简化成:
func_a<42u>();
编译器会自动推导出模板类型参数T是uint32_t,因为42u的原生类型就是uint32_t(如果你传的是不带u的42,那T会被推导为int)。
而你定义的func_b是普通的函数模板:
template<typename T> void func_b(T val) { std::cout << val << std::endl; }
它的推导是函数参数的自动推导,和非类型模板参数的推导逻辑不同,但本质都是编译器帮你省去显式指定类型的步骤。
关键注意事项
- 推导只适用于「非类型模板参数的类型依赖于模板类型参数」的场景,就像
func_a里val的类型是T,而T是待推导的类型参数,这种情况编译器才能反向推导出T。 - C++17还引入了
auto作为非类型模板参数的语法,如果你把func_a改成:
那调用时连类型相关的指定都不用了,直接写template<auto val> void func_a(void) { std::cout << val << std::endl; }func_a<42u>()或者func_a<100>,编译器会自动确定val的具体类型。 - 注意:在C17之前的标准(比如C11/C++14)里,非类型模板参数是不支持自动推导的,必须显式指定所有模板参数。
内容的提问来源于stack exchange,提问作者byteunit
相关产品推荐
相关产品推荐

