Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;如何推断可调用的';模板中的s类型(参数列表和返回值)_C++_Templates_Functional Programming_Variadic Templates_Variadic Functions - Fatal编程技术网

C++ C++;如何推断可调用的';模板中的s类型(参数列表和返回值)

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

基本上,我想做的是制作一个函数模板,它接受任何可调用的函数(函数类型/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;
    }
};

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...); 
         };
}