传递lambda作为模板函数参数 [英] Pass lambda as template function parameter
问题描述
以下代码为什么不编译(在C ++ 11模式下)?
Why doesn't the following code compile (in C++11 mode)?
#include <vector>
template<typename From, typename To>
void qux(const std::vector<From>&, To (&)(const From&)) { }
struct T { };
void foo(const std::vector<T>& ts) {
qux(ts, [](const T&) { return 42; });
}
错误消息是:
prog.cc:9:5: error: no matching function for call to 'qux'
qux(ts, [](const T&) { return 42; });
^~~
prog.cc:4:6: note: candidate template ignored: could not match 'To (const From &)' against '(lambda at prog.cc:9:13)'
void qux(const std::vector<From>&, To (&)(const From&)) { }
^
但这并不能解释为什么它不能与参数匹配。
But it doesn't explain why it couldn't match the parameter.
如果我 qux
是非模板函数,用 T
替换 From
To
与 int
一起编译。
If I make qux
a non-template function, replacing From
with T
and To
with int
, it compiles.
推荐答案
lambda函数不是正常函数。每个lambda都有自己的类型,不是 To(&)(const From&)
。
在您的情况下,非捕获的lambda可以衰减为 To(*)(const From&)
,
A lambda function isn't a normal function. Each lambda has its own type that is not To (&)(const From&)
in any case.
A non capturing lambda can decay to To (*)(const From&)
in your case using:
qux(ts, +[](const T&) { return 42; });
如评论中所述,您可以做到的最好从lambda取出它的方法是这样的:
As noted in the comments, the best you can do to get it out from a lambda is this:
#include <vector>
template<typename From, typename To>
void qux(const std::vector<From>&, To (&)(const From&)) { }
struct T { };
void foo(const std::vector<T>& ts) {
qux(ts, *+[](const T&) { return 42; });
}
int main() {}
注意:我假设推导返回类型和参数类型对于实际问题是强制性的。否则,您可以轻松地将整个lambda推导出为通用可调用对象,并直接使用它,而无需衰减任何东西。
Note: I assumed that deducing return type and types of the arguments is mandatory for the real problem. Otherwise you can easily deduce the whole lambda as a generic callable object and use it directly, no need to decay anything.
这篇关于传递lambda作为模板函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!