C++ C++;如何推断可调用的';模板中的s类型(参数列表和返回值)
基本上,我想做的是制作一个函数模板,它接受任何可调用的函数(函数类型/lambda/Functor),并返回一个lambda,接受类似的args列表并返回原始的返回类型C++ C++;如何推断可调用的';模板中的s类型(参数列表和返回值),c++,templates,functional-programming,variadic-templates,variadic-functions,C++,Templates,Functional Programming,Variadic Templates,Variadic Functions,基本上,我想做的是制作一个函数模板,它接受任何可调用的函数(函数类型/lambda/Functor),并返回一个lambda,接受类似的args列表并返回原始的返回类型 #include <iostream> int func(int a,float b) { return a+b; } struct callable { int operator() (int a, float b) { return a+b; } }; templat
#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);
}
#包括
int func(int a,float b){
返回a+b;
}
结构可调用{
int运算符()(int a,float b){
返回a+b;
}
};
模板
自动获取lambdafromcallable(RV(&func)(参数…){
自动l=[&](参数…参数)->RV{
返回函数(参数…);
};
返回l;
}
int main(){
自动f=getLambdaFromCallable(func);
std::cout您可以将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;
}
如果您可以使用C++17,那么以下工具是否正确:
#include <functional>
template <typename OBJ>
auto getLambdaFromCallable(OBJ&& obj)
{
return [&](const auto&... args) {
return std::invoke(std::forward<OBJ>(obj), args...);
};
}
#包括
模板
自动获取lambdafromcallable(OBJ&&OBJ)
{
返回[&](常量自动&…参数){
返回std::invoke(std::forward(obj),args;
};
}
您可以使用g++-std=c++17
或clang++-5.0-std=c++1z
编译它,这是开箱即用的。->decltype(auto)
用于lambda的返回类型(处理引用)。甚至->decltype(func(std::forward(args)…)
,所以它对SFINAE很友好。@barney试图在第二部分回答您的问题answer@Drax哦,谢谢你,这是解决这个问题的绝佳方法。如果你想重复func(std::forward(args)…,你还可以添加一个异常规范第三次。我有时喜欢C++。谢谢。我假设输入没有被修改,这也简化了关于参数转发的事情,这里我有一个简单的const REF。我也喜欢Drax解决方案,这是在所有细节中解释的。
#include <functional>
template <typename OBJ>
auto getLambdaFromCallable(OBJ&& obj)
{
return [&](const auto&... args) {
return std::invoke(std::forward<OBJ>(obj), args...);
};
}