eml*_*lai 17 c++ lambda templates c++11
为什么以下代码没有编译(在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; });
}
Run Code Online (Sandbox Code Playgroud)
错误消息是:
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&)) { }
^
Run Code Online (Sandbox Code Playgroud)
但它并不能解释为什么它与参数不匹配.
如果我做qux一个非模板函数,替换From用T和To用int,它编译.
sky*_*ack 12
lambda函数不是正常函数.每个lambda都有自己的类型, To (&)(const From&)在任何情况下都不是.在您的情况下,
非捕获lambda可以To (*)(const From&)使用以下方法衰减:
qux(ts, +[](const T&) { return 42; });
Run Code Online (Sandbox Code Playgroud)
正如评论中所指出的,从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() {}
Run Code Online (Sandbox Code Playgroud)
注意:我认为推断返回类型和参数类型对于实际问题是必需的.否则,您可以轻松地将整个lambda推断为通用可调用对象并直接使用它,无需任何衰减.
eml*_*lai 10
如果您不需要使用推导To类型,则可以推断出整个参数的类型:
template<typename From, typename F>
void qux(const std::vector<From>&, const F&) { }
Run Code Online (Sandbox Code Playgroud)
如果我错了,请纠正我,但模板参数推导仅推导出确切的类型而不考虑可能的转换.
因此编译器不能推断To和From对To (&)(const From&)因为qux预计到函数的引用,但您提供有它自己的lambda.