2012-08-14 92 views
0

时,我有以下代码:传递baz重载决议函数模板传递给另一个函数

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正常工作。但是,在传递函数模板bar时,编译器无法推断foo的模板参数T0,即使范围中只有一个bar,并且其第一个参数完全解析为int。如何编写功能模板foo,以便类似foo(bar, 10)这样的调用可以由编译器解决?

回答

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)产生了不同的模板专业化,那将会很奇怪。

+0

是的,我明白了为什么我当前的例子是不可抵扣的原因。我的问题是如何重写函数模板'foo'?换句话说,是否有一些帮助可以在函数定义站点而不是呼叫站点提供编译器,这样可以工作?函数模板作为参数并不是前所未有的。例如,'std :: endl'是一个函数模板。 – keveman 2012-08-14 23:10:54

+0

@keveman“_例如,std :: endl是一个函数模板。”但是'basic_ostream :: operator <<'不是! – curiousguy 2012-08-16 23:13:20

0

你可以这样做:

void (&b)(int,int) = bar; 
    foo(b, 10); 
相关问题