if let birthdate = personInfo?.str_Birthdate {
cell.dobTF.text = birthdate
}
foo 和 bar 之间的唯一区别是 foo 具有可变参数。编译器可以通过某种方式将lambda转换为 bar 中的std :: function。
据我了解,模板类型推导不考虑类型转换。所以都不应该都失败吗?
答案 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)
{}
个特征已经解决了。
在c++17中,您可以这样做:
std
使用c++17演绎指南功能。