【问题标题】:Template argument deduction/substitution failed with lambda as function pointer模板参数推导/替换失败,lambda 作为函数指针
【发布时间】:2018-12-28 09:35:37
【问题描述】:

我想知道为什么在下面的代码中编译器无法使用 lambda 作为函数 foo() 的参数(模板参数推导/替换失败),而一个简单的函数可以工作:

template<class ...Args>
void foo(int (*)(Args...))
{
}

int bar(int)
{
    return 0;
}

int main() {
    //foo([](int) { return 0; }); // error
    foo(bar);
    return 0;
}

intel 编译器(18.0.3 版)

template.cxx(12): error: no instance of function template "foo" matches the argument list
            argument types are: (lambda [](int)->int)
      foo([](int) { return 0; }); // error
      ^
template.cxx(2): note: this candidate was rejected because at least one template argument could not be deduced
  void foo(int (*)(Args...))

有什么想法吗?

【问题讨论】:

标签: c++ templates lambda template-argument-deduction


【解决方案1】:

Template argument deduction 不考虑隐式转换。

类型推导不考虑隐式转换(除了上面列出的类型调整):这是overload resolution 的工作,稍后会发生。

您可以将 lambda 显式转换为函数指针,例如你可以使用static_cast

foo(static_cast<int(*)(int)>([](int) { return 0; }));

operator+,

foo(+[](int) { return 0; });

【讨论】:

  • + 技巧仍然被认为是一种 hack 还是它开始成为一种习语?我不是在问它是否定义明确,我知道它是;它只是添加到代码库的#wtf/line 中吗?
  • @YSC 我不知道,it 非常基于意见。我个人喜欢它,因为它看起来很自然。
  • 为什么不只是+ 而不是那个演员?
  • @Yakk-AdamNevraumont 它的意图可能不够清楚;所以你同意将其视为 YSC 所说的成语吗?
  • 我猜;但不令人惊讶的魔法不如令人惊讶的魔法。有一个狭窄的专业水平,“你不能将该 lambda 传递给期望函数指针的模板函数”令人惊讶,但“哦 operator+”并没有删除它;在该窗口之外,代码会执行您所期望的操作,并且不会令人惊讶。如果+ 没有做“显而易见”的事情,我会说这是有害的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-28
  • 2014-09-22
  • 1970-01-01
  • 1970-01-01
  • 2020-12-08
  • 1970-01-01
相关资源
最近更新 更多