从Lambda function passed as parameter我可以编译示例:
template <class Range>
Range FindFirstIf(Range, bool(*Function)(typename Range::ConstReference value));
struct range { using ConstReference = const float&; };
range rng;
rng = FindFirstIf(rng, [](const float& val) { return (val < 0.0f); });
当然无法链接,因为FindFirstIf
未实现。
然而,当我做了类似的事情时:
template <class Range, class ValueType>
Range MyTest(Range, ValueType, bool(*Function)(ValueType value));
std::vector <int> vi;
double d = 0;
vi = MyTest(vi, d, [](double val) { return (val < 0.0f); });
它有编译错误:
错误C2784:'范围MyTest(范围,ValueType,bool(__ cdecl *)(ValueType))':无法推断'bool(__ cdecl *)(ValueType)'的模板参数 '主::'
为什么呢?我想通过传递d
,ValueType
可以推断为double
?
答案 0 :(得分:2)
改为使用它(请注意+
):
vi = MyTest(vi, d, +[](double val) { return (val < 0.0f); });
在某些情况下,Lambda函数可以衰减到函数指针,但它们不是函数指针。
换句话说,演绎失败是因为它期望在函数指针上工作,但lambda不是函数指针,当然可以转换它,但首先必须进行演绎,但它不能用于lambda而不是期望的类型,它可能会腐烂......依此类推。
通过在lambda前面添加+
,可以在将转换传递给函数之前强制转换,因此MyTest
会按预期接收实际的函数指针并继续扣除。
以下是基于代码的最小工作示例:
#include<vector>
template <class Range, class ValueType>
Range MyTest(Range, ValueType, bool(*Function)(ValueType value)) {}
int main() {
std::vector <int> vi;
double d = 0;
vi = MyTest(vi, d, +[](double val) { return (val < 0.0f); });
}