如果模板没有可变参数,则将Lambda推导为std :: function

时间:2018-10-17 08:19:54

标签: c++ c++11 visual-c++-2015

if let birthdate = personInfo?.str_Birthdate {
    cell.dobTF.text = birthdate
}

foo bar 之间的唯一区别是 foo 具有可变参数。编译器可以通过某种方式将lambda转换为 bar 中的std :: function。

据我了解,模板类型推导不考虑类型转换。所以都不应该都失败吗?

2 个答案:

答案 0 :(得分:10)

对于bar的类型参数没有任何推论,它们已完全指定。

您仍然可以从foo中推导出包的尾部,但是失败了,因为lambda不是std::function

答案 1 :(得分:6)

go mod

现在,template<typename ReturnT, typename... ParamT> void foo(std::function<ReturnT(ParamT...)> callback) {} foo<int,int>

它没有完全指定foo<ReturnT=int, ParamsT starts with {int}>。实际上,没有办法完全指定ParamT

作为未完全指定的模板,推导发生并且失败。它不会尝试“如果我只是假设包装不会继续下去怎么办”。

您可以使用以下方法解决此问题:

ParamT

template<typename ReturnT, typename... ParamT> void foo(block_deduction<std::function<ReturnT(ParamT...)>> callback) {} 如下:

block_deduction

现在推论在template<class T> struct block_deduction_helper { using type=T; }: template<class T> using block_deduction = typename block_deduction_helper<T>::type; 的第一个参数上被阻止。

您的代码有效。

当然,如果您传递foo,它将不再自动推论参数。

请注意,推导类型擦除类型(例如std::function)的类型通常是代码异味。

同时替换为:

std::function

如果必须获取参数,请使用函数特征助手(在SO上有很多)。如果您只需要返回值,那么已经有template<class F> void bar(F callback) {} 个特征已经解决了。


中,您可以这样做:

std

使用演绎指南功能。