将一个函数模板传递给另一个函数时的重载解决

Overload resolution when passing in a function template to another function

本文关键字:函数 另一个 解决 重载 函数模板 一个      更新时间:2023-10-16

我有以下代码:

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;
}

传入baz时,foo的重载分辨率工作正常。但是,当传入函数模板bar时,编译器无法推断出foo的模板参数T0,即使作用域中只有一个bar,并且其第一个参数完全解析为int。如何编写函数模板foo以便编译器可以解析像foo(bar, 10)这样的调用?

14.8.2.1/6(从函数调用中推导模板参数)回答了这个问题:

P是函数类型、指向函数类型的指针或指向成员函数类型的指针时:

  • 如果参数是包含一个或多个函数模板的重载集,则该参数将被视为非推导上下文。

在您的情况下,bar 是一个函数模板,因此参数k是函数类型,其重载集包含函数模板。因此,bar<T>的模板参数是不可推导的。

作为实际原因,请考虑foo(bar<int>, 10)foo(bar<long>, 10)都是完全可行的调用,并且不会隐式为您做出选择。请记住,整数文本的类型取决于,如果foo(bar, 10)foo(bar, 100000000)产生不同的模板专用化,那将很奇怪。

你可以做:

  void (&b)(int,int) = bar;
  foo(b, 10);