为什么以下函数不会覆盖(lambda作为第一个参数)?
template<typename ...Args>
void call(Args&& ...args) {
std::cout << "call 1";
}
template<typename ...Args>
void call(CustomObject object, Args&& ...args) {
std::cout << "call 2";
}
// see this function
template<typename ...Args>
void call(std::function<void ()>, Args&& ...args) {
std::cout << "call 3";
}
call()
输出'致电1' call(CustomObject())
输出'调用2' call([](){})
输出'致电1' // 错误 为什么call([](){})
没有输出'调用3'?
我应该如何声明让call([](){})
输出'调用3'的函数?
编辑: @KennyTM给出了上述答案。
template<typename F, typename ...Args>
auto call(F&& f, Args&& ...args)
-> typename std::enable_if<std::is_same<decltype(f()), void>::value>::type
{
std::cout << "call 3\n";
}
但是......如果lambda有参数怎么办?像这样:
class CustomObject {};
template<typename ...Args>
void call(std::function<void (CustomObject *)>, Args&& ...args) {
std::cout << "call 4";
}
如何让call([](CustomObject *){})
输出'调用4'?
编辑: @ildjarn给出了答案:
template<typename F, typename ...Args>
auto call(F&& f, Args&& ...)
-> typename std::enable_if<std::is_same<decltype(f( std::declval<CustomObject*>() )), void>::value>::type
{
std::cout << "call 4\n";
}
答案 0 :(得分:6)
lambda的类型是匿名类型,其operator()
。它不是std::function<>
。
您可以检查第一个参数是否为调用3(demo:http://ideone.com/IQ4N6L)的仿函数,而不是专门化类型:
#include <iostream>
#include <type_traits>
template<typename F, typename ...Args>
auto call(F&& f, Args&& ...args)
-> typename std::enable_if<std::is_same<decltype(f()), void>::value>::type
{
std::cout << "call 3\n";
}
template<typename ...Args>
void call(Args&& ...args) {
std::cout << "call 1\n";
}
int main() {
call(1);
call([](){});
}