当前位置: 首页 > 知识库问答 >
问题:

C++模板推导不起作用

越安翔
2023-03-14

对于以下代码:

#include<functional>
template<typename T>
void f(std::function<void(T)> g) {
}

template<typename T>
void g(T x) {
}

int main() {
   f(&g<int>);
}

C++14编译器产生错误:

 no matching function for call to 'f(<unresolved overloaded function type>)'
     f(&g<int>);

我很好奇为什么模板参数推导在这里不起作用。似乎,假定g的参数是int类型,我们可以推断f的参数是std::function 类型,因此f中的t=int。为什么没有发生这种情况?我对C++标准中解释这一点的相关部分很感兴趣。T是否出现在这里的非推导上下文中?

#include<vector>
template<typename T>
void f(std::vector<T> vec) { 
}


int main() {
    f(std::vector<int>{});
}

因此,创建非推导上下文的不是尖括号。

共有1个答案

楚奇逸
2023-03-14

您的函数需要std::function类型的参数,但您传递给它的是函数指针。&g 可转换为std::function参数类型,但是模板参数的推导要求完全匹配(除了[temp.duct.call]/2,3,4允许的调整之外),因此不考虑用户定义的转换。

编写f(std::function (G )) 是可行的,因为您现在传递的是std::function,所以模板参数推导将会成功。

f (&g ) 也可以工作,因为您现在已经显式指定了t,所以它不再参与模板参数的推导,并且将尝试用户定义的转换。

 类似资料:
  • 我已经编写了一个具有递归评估的可变参数模板函数。对于最后一个参数,我在没有可变参数包的情况下实现了专业化,并且一切正常。 现在我想把可变函数参数转换成模板参数。 这是我的尝试: gcc和clang报告了一个模糊的过载,并且无法使用空参数包在“专业化”和“可变参数”之间做出决定。 我尝试删除特化并检查可变参数模板中的包大小,但是如果没有特化,编译器就无法推断出参数“p”。

  • 当我用PHP curl发送这个json数据到Facebook Messenger Bot api时,它工作正常。 $jsonData='{“收件人”:{“id”:“'.$sender.”“}”,消息:{“文本”:“'.$obj.”“}”; 但是,当我从FB页面使用模板。模板不起作用 我试图编码成Json,替换一个按钮,什么都没发生。Facebook模板在messenger更新后无法使用,或者我需要

  • 问题内容: 我想尝试使用模板文字,但它不起作用:它显示文字变量名称,而不是值。我正在使用Chromev50.0.2(和jQuery)。 例: 输出: 问题答案: JavaScript 模板文字 需要反引号,而不是直接引号。 您需要使用反引号(也称为“重音符”-您会在1键旁边找到)-而不是单引号-来创建模板文字。 反引号在许多编程语言中都很常见,但可能对JavaScript开发人员来说是新的。 范例

  • 我的MySQL工作台6.0(我在Ubuntu上工作)有问题,当我选择一个服务器实例时,它显示的不是“SCHEMAS”面板,而是消息“No object selected”。在“SQL面板”(主面板)中,查询<code>显示数据库有效,但我在“SCHEMAS”面板中没有数据库列表。 我的所有实例都有这个问题,当有很多数据库和表时,这很烦人! 你对这个问题有什么想法吗? 谢谢,

  • 使用以下代码生成时 生成以下诊断(代码后): 诊断: 有趣的部分不是关于歧义错误本身(这不是这里主要关注的问题)。有趣的是,当仅使用函数名调用fun时,第一个fun的模板参数F被解析为纯函数类型double(double),而第二个fun的模板参数F被解析为更期望的函数指针类型。 然而,当我们将调用<代码>乐趣(测试) 更改为<代码>乐趣( 这种行为似乎是所有Clang和GCC(以及Visual

  • 另一个有用的可能示例:(伪代码)