C++函数模板实参推导失败(<unresolved overloaded function type>)问题咨询
C++模板实参推导问题解答
先附上问题对应的代码:
#include<iostream> template<int var, typename T> void func (T x) { std::cout<<x<<std::endl; } template<typename T> void SomeFunc(T a) { a(6); } int main() { func<5, int>(10);//this work as expected func<5>(20);//this works as well using template argument deduction SomeFunc(func<5,int>) ;//this works as well //the next two calls doesn't work SomeFunc(func<5>);//this doesn't work. Why doesn't template argument deduction works here SomeFunc(func<5>(20));//this doesn't work either. return 0; }
问题1:SomeFunc(func<5>);调用失败原因
- 你的分析基本正确,补充细节如下:
func是包含两个模板参数的函数模板,第一个为int类型非类型参数,第二个为类型参数T。你仅指定了第一个非类型参数5,第二个类型参数T需要通过模板实参推导确定。- 模板实参推导不会在该场景触发:当你将
func<5>作为参数传递给SomeFunc时,编译器需要先推导SomeFunc的模板参数T的类型,但此时func<5>是未完成实例化的函数模板,没有确定的类型,无法用于推导T。 - 额外说明:
SomeFunc的模板参数推导仅看调用点传入的实参类型,不会回溯SomeFunc内部的a(6)调用逻辑来反推T的类型,因此无法通过后续调用的参数6推导func的T为int。
问题2:SomeFunc(func<5>(20));调用失败原因
func<5>(20)是函数调用表达式,func的返回值类型为void,你实际是将一个void类型的结果传入SomeFunc。- 此时
SomeFunc的模板参数T会被推导为void,但SomeFunc内部需要执行a(6),无法对void类型的值进行调用操作,因此编译失败。 - 注意该写法传入的是
func执行后的返回值,不是可调用的函数实例,和之前传入函数指针/函数对象的场景完全不同。
问题3:“Deduction only works for immediate calls”的含义
- 这句话翻译为:模板实参推导仅适用于立即调用场景。
- 具体含义:函数模板的实参推导,只有在你直接书写
函数模板名(调用实参列表)这种立即调用的形式时才会触发。如果你只是将未完全指定模板参数的函数模板作为值传递给其他位置(比如作为其他函数的参数、赋值给变量等),而没有立刻调用它,编译器不会自动推导剩余的模板参数,也不会将其转换为具体的函数实例,你必须手动指定所有模板参数才能得到确定类型的函数实例。
内容的提问来源于stack exchange,提问作者Anoop Rana
相关产品推荐
相关产品推荐

