bar*_*ney 4 c++ templates functional-programming variadic-functions variadic-templates
基本上我想要做的是创建一个函数模板,它接受任何Callable(函数类型/ lambda/Functor)并返回一个lambda-taking-the-similar-args-list并返回原始类型的返回类型
#include <iostream>
int func(int a,float b) {
return a+b;
}
struct callable {
int operator() (int a, float b) {
return a+b;
}
};
template <typename RV, typename... Args>
auto getLambdaFromCallable(RV(&func)(Args...)) {
auto l = [&](Args... args) -> RV {
return func(args...);
};
return l;
}
int main() {
auto f = getLambdaFromCallable(func);
std::cout << f(1,2.f);
std::cout << " " << typeid(f).name();
auto f2 = getLambdaFromCallable(callable{}); // doesn't work
callable{}(1,2); // works
auto lambdaTest = [](int a, float b) -> int {
return a+b;
};
auto f3 = getLambdaFromCallable(lambdaTest);
}
Run Code Online (Sandbox Code Playgroud)
你可以getLambdaFromCallable改为:
template <typename F>
auto getLambdaFromFunction(const F& func) {
auto l = [&](auto&&... args)
-> decltype(func(std::forward<decltype(args)>(args)...)) {
return func(std::forward<decltype(args)>(args)...);
};
return l;
}
Run Code Online (Sandbox Code Playgroud)
这背后的原因是,由于你无法得到一个详尽的参数列表,你可以调用一个函数对象(首先可能有多个重载),你也可以使用一个通用的lambda来接受所有东西并将它转发给调用.
详细说明这是如何工作的:
该auto&&...部分将转换为lambda调用运算符上的模板参数列表.
F被推断为你所谓的getLambdaFromFunctionwith(没有const和引用,但如果需要可以改变).
decltype(args)只是在那里使用std::forward反过来正确地转发左值和左值引用,请参阅std :: forward以获取更多详细信息.
生成的lambda对象如下所示:
template <typename F>
class generatedLambda
{
public:
template <typename... Args>
auto operator()(Args&&... args) -> decltype(func(std::forward<decltype(args)>(args)...))
{
return func(std::forward<decltype(args)>(args)...);
}
private:
F func;
};
Run Code Online (Sandbox Code Playgroud)