【问题标题】:Why does this template argument deduction/overload resolution fail?为什么这个模板参数推导/重载解析失败?
【发布时间】:2019-02-20 10:36:19
【问题描述】:

这段代码 sn-p 在MSVCClangGcc 中编译失败,(它们给出不同的错误信息):

int foo(int a, int b) {
    return a + b;
}

template <class Ret, class A, class B>
void foo(Ret (*)(A, B)) {

}

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

这不应该编译吗?我不明白为什么它无法解析重载函数或推导模板参数。欢迎任何帮助,谢谢。

PS:如果模板被替换为void foo(int (*)(int, int)),或者我们重命名foo 之一以避免重载,它将编译。

【问题讨论】:

  • 递归函数模板重载解析?祝所有深入研究的人好运……

标签: c++ templates language-lawyer overload-resolution


【解决方案1】:

为简单起见,我们将第一个重载称为foo1,将第二个重载称为foo2

使用模板,问题是你无法推断出外部foo的模板参数,根据[temp.deduct.call]/6

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

在没有模板的情况下,程序会考虑foo1(foo1)foo1(foo2)foo2(foo1)foo2(foo2) 的所有可能性并选择唯一可行的foo2(foo1),根据[over.over]/6

[ 注意:如果f()g() 都是重载函数,则交叉 必须考虑可能性的乘积来解决f(&amp;g),或者 等效表达式f(g)。 — 尾注 ]

【讨论】:

  • 也许补充一点,非推导上下文意味着模板是 not considered 外部 foo()
猜你喜欢
  • 1970-01-01
  • 2019-10-22
  • 2012-02-07
  • 2017-01-27
  • 1970-01-01
  • 2021-08-14
  • 2012-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多