C++模板实参推导:gcc编译通过但clang/msvc不行,谁符合标准?
问题解答
根据最新的C标准(C20及后续版本),Clang和MSVC的行为是正确的,GCC的行为属于非标准扩展。
核心原因分析:
当你写func(f)时,f是一个函数模板的名字,它本身代表的是一个重载集(即使这里只有一个模板,它也对应无数个可能的实例化版本)。要推导func的模板参数T,编译器需要明确知道f对应的具体函数类型,但此时f没有提供显式的模板实参,标准并不允许编译器自动使用f的默认模板参数(int)来完成实例化推导。
标准规定:函数模板名在作为模板实参传递时,必须有足够的上下文来唯一确定一个具体的实例化类型。而func(f)的场景中,没有这样的上下文——func的参数T可以是任意void()类型(对应f的任意T实例),编译器无法自动选定默认的int版本来完成推导。
而func(f<>)则显式要求编译器使用f的默认模板参数实例化出void f<int>(),此时传递的是一个明确的函数类型,所有编译器都能正确推导func的模板参数T为void(*)()。
内容的提问来源于stack exchange,提问作者user19414420
相关产品推荐
相关产品推荐

