当将重载函数作为参数时,模板参数推导如何工作? [英] How does template argument deduction work when an overloaded function is involved as an argument?
问题描述
这是
This is the more sophisticated question mentioned in How does overload resolution work when an argument is an overloaded function?
下面的代码编译没有任何问题:
void foo() {}
void foo(int) {}
void foo(double) {}
void foo(int, double) {}
// Uncommenting below line break compilation
//template<class T> void foo(T) {}
template<class X, class Y> void bar(void (*f)(X, Y))
{
f(X(), Y());
}
int main()
{
bar(foo);
}
对于模板自变量的推论似乎不是一项艰巨的任务-只有一个函数foo()
接受两个自变量.但是,取消注释foo()
的模板重载(仍然只有一个参数)不会毫无原因地中断编译.使用gcc 5.x/6.x和clang 3.9编译都会失败.
It doesn't appear a challenging task for template argument deduction - there is only one function foo()
that accepts two arguments. However, uncommenting the template overload of foo()
(which still has just a single parameter) breaks compilation for no obvious reason. Compilation fails both with gcc 5.x/6.x and clang 3.9.
可以通过重载解析/模板参数推导的规则来解释它,还是应该将其视为那些编译器中的缺陷?
Can it be explained by the rules of overload resolution/template argument deduction or it should be qualified as a defect in those compilers?
推荐答案
如所链接问题的答案中所述:
As noted in the answer to your linked question:
[temp.deduct.call]/6:
当P
是函数类型时,指向函数类型的指针或指向成员函数类型的指针:
[temp.deduct.call]/6:
WhenP
is a function type, pointer to function type, or pointer to member function type:
-如果参数是包含一个或多个函数模板的重载集,则将参数视为 作为非推论上下文.
— If the argument is an overload set containing one or more function templates, the parameter is treated as a non-deduced context.
由于重载集包含一个功能模板,因此该参数被视为非推导上下文.这会导致模板参数推导失败:
Since the overload set contains a function template, the parameter is treated as a non-deduced context. This causes template argument deduction to fail:
[temp.deduct.type]/4:
[...]如果仅在非推导中使用模板参数 上下文且未明确指定,模板参数推导失败.
[temp.deduct.type]/4:
[...]If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
这个失败的推论给你你的错误.请注意,如果您明确指定参数,则代码将成功编译:
And this failed deduction gives you your error. Note that if you explicitly specify the arguments, the code compiles successfully:
bar<int,double>(foo);
这篇关于当将重载函数作为参数时,模板参数推导如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!