为什么下面的代码不能编译(在 C++11 模式下)?
#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&)) { }
^
但它并没有解释为什么它不能匹配参数。
如果我将 qux
设为非模板函数,则将 From
替换为 T
并将 To
替换为 int
,它会编译。
最佳答案
lambda 函数不是普通函数。每个 lambda 都有自己的类型在任何情况下都不是 To (&)(const From&)
。
在您的情况下,非捕获 lambda 可以衰减为 To (*)(const From&)
:
qux(ts, +[](const T&) { return 42; });
如评论中所述,从 lambda 中取出它的最佳方法是:
#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 推导出为一个通用的可调用对象并直接使用它,无需衰减任何东西。
关于c++ - 将 lambda 作为模板函数参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41920890/