我有以下代码:
template<typename T>
void bar(int x, T y)
{
}
void baz(int x, int y)
{
}
template<typename T0, typename T1>
void foo(void k(T0, T1), T1 t)
{
}
int main()
{
foo(baz, 10); // OK
foo(bar, 10); // ERROR
return 0;
}
传递foo
时,baz
的重载分辨率可正常工作。但是,在传递函数模板bar
时,编译器无法推断T0
的模板参数foo
,即使范围中只有一个bar
,并且它的第一个参数完全解析为int
。如何编写函数模板foo
,以便编译器可以解析foo(bar, 10)
之类的调用?
答案 0 :(得分:0)
14.8.2.1/6(从函数调用中扣除模板参数)回答这个问题:
当
P
是函数类型时,指向函数类型的指针或指向成员函数类型的指针:
- 如果参数是包含一个或多个函数模板的重载集,则该参数将被视为非推导的上下文。
在您的情况下,bar
是一个函数模板,因此参数k
是函数类型,其重载集包含函数模板。因此bar<T>
的模板参数不可推导。
作为一个实际原因,请考虑foo(bar<int>, 10)
和foo(bar<long>, 10)
都是完全可行的调用,并且不会隐式地为您做出选择。请记住,整数文字的类型取决于值,如果foo(bar, 10)
和foo(bar, 100000000)
生成不同的模板特化,则会很奇怪。
答案 1 :(得分:0)
你可以这样做:
void (&b)(int,int) = bar;
foo(b, 10);