我怎样才能最好的定义模板功能applyFunc匹配拉姆达的签名?
只要您接受只使用非捕获lambda表达式(就像您在示例代码中所做的那样),就可以利用它们衰减到函数指针的事实。
作为最小的,工作示例:
template<class E>
int applyFunc(int(*f)(E)) {
return f(E{});
}
int main() {
auto asLambda = [](int d) -> int { return d+d; };
applyFunc(+asLambda);
}
如果你想使用捕捉lambda表达式来代替,你可以提取类型E
不知何故,如果你接受如下:
- 你必须使用一个通用的类型
F
代替std::function
- 不能使用通用的Lambda表达式
然后,你可以直接看看你的lambda的operator()
。
它遵循最小,工作示例:
template<typename F>
struct GetFrom {
template<typename R, typename E>
static E typeE(R(F::*)(E) const);
// required for mutable lambdas
template<typename R, typename E>
static E typeE(R(F::*)(E));
};
template<class F>
int applyFunc(F f) {
using E = decltype(GetFrom<F>::typeE(&F::operator()));
return f(E{});
}
int main() {
int i = 0;
applyFunc([i](int d) mutable -> int { return d+d; });
applyFunc([i](int d) -> int { return d+d; });
}
你可以很容易地扩展到多个参数,如果你需要。使用std::tuple
作为返回类型,并从中获取第i个类型。
最后,如果你想使用捕捉lambda表达式并将它们分配到一个std::function
无论出于何种原因,要知道,E
不能自动推断,因此必须显式地指定它(由@在评论的问题建议cpplearner):
applyFunc<int>([](int d) { return d+d; })
EDIT
GetFrom
也可以在SFINAE表达式直接使用,作为热曲在评论中提到。
作为最小的,工作示例:
#include<type_traits>
template<typename F>
struct GetFrom {
template<typename R, typename E>
static E typeE(R(F::*)(E) const);
// required for mutable lambdas
template<typename R, typename E>
static E typeE(R(F::*)(E));
};
template<class F, typename E = decltype(GetFrom<F>::typeE(&F::operator()))>
std::enable_if_t<std::is_same<E, int>::value, E>
applyFunc(F f) {
return f(E{});
}
template<class F, typename E = decltype(GetFrom<F>::typeE(&F::operator()))>
std::enable_if_t<std::is_same<E, double>::value, E>
applyFunc(F f) {
return f(E{});
}
int main() {
int i = 0;
applyFunc([i](int d) mutable -> int { return d+d; });
applyFunc([i](double d) -> int { return d+d; });
// this won't compile, as expected
// applyFunc([i](char d) -> int { return d+d; });
}
'applyFunc([](INT d){返回d + d;})' –
cpplearner
用户定义的转换不模板参数推导过程中考虑。所以'E'不能推导出来,除非参数的类型是'std :: function';仅仅可以转换成这种类型是不够的。您可以通过@cpplearner显示,明确指定'E'。 –
查看相关列表......“重载std :: function参数以匹配lambda”,“lambda的模板参数演绎”等。_all_回答你的问题,不是? – ildjarn