模板类型推导如何使用重载函数作为参数

巴鲁克

看这个(简化的)例子:

int foo(int) { return 0;}
double foo(double) { return 0.0; }

template <class T>
enable_if<is_integral<T>::value>
bar(T(*f)(T)) {}

int main()
{
   bar(foo);
   return 0;
}

我的期望是,编译器将首先尝试为每个重载实例化模板,第二个重载将失败(SFINAE),因此void bar(int(*f)(int),候选集中将只剩下候选者,这将使用的第一个重载来解决foo那不是什么。失败的原因是这样的:

no matching function for call to ‘bar(<unresolved overloaded function type>)’
couldn't deduce template parameter ‘T’

有什么办法可以实现这样的目标吗?

杰夫·加勒特

C ++的类型推导非常简单。[temp.deduct.call] /6.2[over.over] / 1子句描述了将重载名称用作参数的方式。

在您的示例中,两个推论都将成功(到T=intT=double),一次替代将失败。但是语言只要求成功演绎一次。

您问如何实现它。以下是一些选项:

  1. 不要使用重载名称static_cast到所需的函数类型,也不要在对bar的调用中显式提供T的类型。
  2. 更改过载,以便仅对过载之一进行演绎。换句话说,通过演绎而不是替代来排除超载。参见以下示例。
  3. 添加另一个可以推导T的参数。
  4. 通过降压,并避免推导T直到以后。

#2的示例:

tempate<class T> struct integral_wrapper { T t; }

integral_wrapper<int> foo(int);
double foo(double);

template<class T>
void bar(integral_wrapper<T> foo(T));

#3的示例:

template<class T>
void bar(T (*f)(T), T);

bar(foo, 0);

#4的示例:

struct foo_t
{
    int operator()(int);
    double operator()(double);
} foo;

template<class F>
void bar(F);

bar(foo);

请注意,通用Lambda可能是#4的另一种方法。

根据您的使用情况,其中一些可能比其他更具吸引力。将参数传递给STL算法时,方法4特别有用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

当将重载函数作为参数时,模板参数推导如何工作?

如何使用模板模板类型作为函数参数?

使用原始指针作为参数的函数模板推导

如何使模板推导带有可变参数的函数的返回类型

函数类型参数的模板参数推导

通过参数计数推导重载成员函数的函数参数类型

类型推导失败:将派生模板的shared_ptr转换为基本模板作为函数参数

C ++:将lambda作为带有模板参数的函数进行传递会使推导模板类型失败

使用额外的不可推导模板参数重载函数是否有效?

为什么模板参数推导在重载函数中失败?

使用函数的返回类型和参数类型作为模板类型

使用模板重载函数类型

重载模板函数推导错误

C ++重载函数作为模板参数

如何使用模板类型作为函数参数派生抽象模板类(C ++ 11)

在C ++中将函数作为模板类型传递并推导其类型

模板函数参数推导

此模板类型推导和重载解析如何工作?

使用派生的模板参数类型作为函数的返回类型(CRTP)?

函数模板中返回类型的模板参数推导

非类型模板参数中的占位符类型可以涉及作为模板参数传递的函数的重载解析吗?

使用函数指针作为模板函数类型参数?

模板参数的模板类型推导

可变参数模板函数参数和引用类型推导

为什么不能在函数中使用模板别名作为参数并自动推导?

如何为函数类型使用模板参数?

模板参数推导/替换失败,以lambda作为函数指针

如何使用函数作为参数重载operator <<(如cout的endl)?

如何使用任意类型作为函数参数?