Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.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++;将捕获作为函数指针的lambda 我玩的是C++ LAMBDAS,它们的隐式转换为函数指针。我的起始示例是使用它们作为ftw函数的回调。这正如预期的那样有效 #include <ftw.h> #include <iostream> using namespace std; int main() { auto callback = [](const char *fpath, const struct stat *sb, int typeflag) -> int { cout << fpath << endl; return 0; }; int ret = ftw("/etc", callback, 1); return ret; } #包括 #包括 使用名称空间std; int main() { 自动回调=[](常量字符*fpath,常量结构stat*sb, int-typeflag)->int{ cout_C++_Lambda_Function Pointers_C++11 - Fatal编程技术网 int{ cout,c++,lambda,function-pointers,c++11,C++,Lambda,Function Pointers,C++11" /> int{ cout,c++,lambda,function-pointers,c++11,C++,Lambda,Function Pointers,C++11" />

C++;将捕获作为函数指针的lambda 我玩的是C++ LAMBDAS,它们的隐式转换为函数指针。我的起始示例是使用它们作为ftw函数的回调。这正如预期的那样有效 #include <ftw.h> #include <iostream> using namespace std; int main() { auto callback = [](const char *fpath, const struct stat *sb, int typeflag) -> int { cout << fpath << endl; return 0; }; int ret = ftw("/etc", callback, 1); return ret; } #包括 #包括 使用名称空间std; int main() { 自动回调=[](常量字符*fpath,常量结构stat*sb, int-typeflag)->int{ cout

C++;将捕获作为函数指针的lambda 我玩的是C++ LAMBDAS,它们的隐式转换为函数指针。我的起始示例是使用它们作为ftw函数的回调。这正如预期的那样有效 #include <ftw.h> #include <iostream> using namespace std; int main() { auto callback = [](const char *fpath, const struct stat *sb, int typeflag) -> int { cout << fpath << endl; return 0; }; int ret = ftw("/etc", callback, 1); return ret; } #包括 #包括 使用名称空间std; int main() { 自动回调=[](常量字符*fpath,常量结构stat*sb, int-typeflag)->int{ cout,c++,lambda,function-pointers,c++11,C++,Lambda,Function Pointers,C++11,由于捕获lambda需要保留一个状态,因此实际上没有简单的“解决方法”,因为它们不仅仅是普通函数。函数指针的意义在于它指向一个单一的全局函数,而这些信息没有空间容纳状态 最接近的解决方法(本质上放弃状态性)是提供某种类型的全局变量,可从lambda/函数访问。例如,您可以创建一个传统的functor对象,并为其提供一个引用某个唯一(全局/静态)实例的静态成员函数 但这有点违背了捕获兰姆达斯的全部目的。我刚刚遇到了这个问题 代码在没有lambda捕获的情况下可以正常编译,但lambda捕获存在类型

由于捕获lambda需要保留一个状态,因此实际上没有简单的“解决方法”,因为它们不仅仅是普通函数。函数指针的意义在于它指向一个单一的全局函数,而这些信息没有空间容纳状态

最接近的解决方法(本质上放弃状态性)是提供某种类型的全局变量,可从lambda/函数访问。例如,您可以创建一个传统的functor对象,并为其提供一个引用某个唯一(全局/静态)实例的静态成员函数


但这有点违背了捕获兰姆达斯的全部目的。

我刚刚遇到了这个问题

代码在没有lambda捕获的情况下可以正常编译,但lambda捕获存在类型转换错误

使用C++11的解决方案是使用
std::function
(编辑:本例后面显示了另一个不需要修改函数签名的解决方案)。您也可以使用
boost::function
(实际上运行得更快).示例代码-更改以使其能够编译,使用gcc 4.7.1编译:

#include <iostream>
#include <vector>
#include <functional>

using namespace std;

int ftw(const char *fpath, std::function<int (const char *path)> callback) {
  return callback(fpath);
}

int main()
{
  vector<string> entries;

  std::function<int (const char *fpath)> callback = [&](const char *fpath) -> int {
    entries.push_back(fpath);
    return 0;
  };

  int ret = ftw("/etc", callback);

  for (auto entry : entries ) {
    cout << entry << endl;
  }

  return ret;
}
#包括
#包括
#包括
使用名称空间std;
intftw(常量字符*fpath,std::函数回调){
返回回调(fpath);
}
int main()
{
向量条目;
std::函数回调=[&](const char*fpath)->int{
条目。推回(fpath);
返回0;
};
int-ret=ftw(“/etc”,回调);
用于(自动输入:输入){
我们在这里找到了答案:

它将
lambda指针
转换为
void*
并在需要时转换回

  • 作废*
  • 自动失效函数=新的decltype(to_函数(lambda))(to_函数(lambda))

  • void*

    自动功能=静态转换( 空隙率函数)


  • 将捕获lambda转换为函数指针是一种很有技巧的方法,但在使用它时需要小心:

    您的代码将如下所示(警告:brain compile):

    intmain()
    {
    向量条目;
    auto const callback=cify([&](const char*fpath,const struct stat*sb,
    int-typeflag)->int{
    条目。推回(fpath);
    返回0;
    });
    int-ret=ftw(“/etc”,回调,1);
    用于(自动输入:输入){
    
    呵呵,这是个老问题,但还是

    #include <iostream>
    #include <vector>
    #include <functional>
    
    using namespace std;
    
    // We dont try to outsmart the compiler...
    template<typename T>
    int ftw(const char *fpath, T callback) {
      return callback(fpath);
    }
    
    int main()
    {
      vector<string> entries;
    
      // ... now the @ftw can accept lambda
      int ret = ftw("/etc", [&](const char *fpath) -> int {
        entries.push_back(fpath);
        return 0;
      });
    
      // ... and function object too 
      struct _ {
        static int lambda(vector<string>& entries, const char* fpath) {
          entries.push_back(fpath);
          return 0;
        }
      };
      ret = ftw("/tmp", bind(_::lambda, ref(entries), placeholders::_1));
    
      for (auto entry : entries ) {
        cout << entry << endl;
      }
    
      return ret;
    }
    
    #包括
    #包括
    #包括
    使用名称空间std;
    //我们不会试图智取编译器。。。
    样板
    int ftw(常量字符*fpath,T回调){
    返回回调(fpath);
    }
    int main()
    {
    向量条目;
    //…现在@ftw可以接受lambda
    int ret=ftw(“/etc”,[&](常量字符*fpath)->int{
    条目。推回(fpath);
    返回0;
    });
    //…还有函数对象
    结构{
    静态int lambda(向量和条目,常量字符*fpath){
    条目。推回(fpath);
    返回0;
    }
    };
    ret=ftw(“/tmp”,bind(216;::lambda,ref(条目),占位符::1));
    用于(自动输入:输入){
    
    cout原创

    Lambda函数非常方便,并且减少了代码。在我的例子中,我需要Lambda进行并行编程。但是它需要捕获和函数指针。我的解决方案就在这里。但是要注意捕获的变量的范围

    template<typename Tret, typename T>
    Tret lambda_ptr_exec(T* v) {
        return (Tret) (*v)();
    }
    
    template<typename Tret = void, typename Tfp = Tret(*)(void*), typename T>
    Tfp lambda_ptr(T& v) {
        return (Tfp) lambda_ptr_exec<Tret, T>;
    }
    
    带有返回值的示例

    int a = 100;
    auto b = [&]() {return a;};
    int (*fp)(void*) = lambda_ptr<int>(b);
    fp(&b);
    
    将带有捕获的lambda转换为C指针

    void (*f1)(void*) = Lambda::ptr(b);
    f1(nullptr);
    printf("%d\n", a);  // 101 
    
    也可以这样使用

    auto f2 = Lambda::ptr(b);
    f2(nullptr);
    printf("%d\n", a); // 102
    
    在这种情况下,应使用返回值

    int (*f3)(void*) = Lambda::ptr<int>(b);
    printf("%d\n", f3(nullptr)); // 103
    
    int(*f3)(void*)=Lambda::ptr(b);
    printf(“%d\n”,f3(nullptr));//103
    
    如果使用了数据

    auto b2 = [&](void* data) {return *(int*)(data) + a;};
    int (*f4)(void*) = Lambda::ptr<int>(b2);
    int data = 5;
    printf("%d\n", f4(&data)); // 108
    
    autob2=[&](void*data){return*(int*)(data)+a;};
    int(*f4)(void*)=Lambda::ptr(b2);
    int数据=5;
    printf(“%d\n”,f4(&data));//108
    
    使用局部全局(静态)方法,可以按以下步骤进行

    template <class F>
    auto cify_no_args(F&& f) {
      static F fn = std::forward<F>(f);
      return [] {
        return fn();
      };
    }
    
    因此,用法将是

    some_c_func(cify_no_args([&] {
      // code
    }));
    
    这是因为每个lambda都有一个唯一的签名,所以使其成为静态并不成问题

    template <class F>
    struct lambda_traits : lambda_traits<decltype(&F::operator())>
    { };
    
    template <typename F, typename R, typename... Args>
    struct lambda_traits<R(F::*)(Args...)> : lambda_traits<R(F::*)(Args...) const>
    { };
    
    template <class F, class R, class... Args>
    struct lambda_traits<R(F::*)(Args...) const> {
        using pointer = typename std::add_pointer<R(Args...)>::type;
    
        static pointer cify(F&& f) {
            static F fn = std::forward<F>(f);
            return [](Args... args) {
                return fn(std::forward<Args>(args)...);
            };
        }
    };
    
    template <class F>
    inline lambda_traits<F>::pointer cify(F&& f) {
        return lambda_traits<F>::cify(std::forward<F>(f));
    }
    

    我的解决方案是,只使用一个函数指针来引用静态lambda

    typedef int (* MYPROC)(int);
    
    void fun(MYPROC m)
    {
        cout << m(100) << endl;
    }
    
    template<class T>
    void fun2(T f)
    {
        cout << f(100) << endl;
    }
    
    void useLambdaAsFunPtr()
    {
        int p = 7;
        auto f = [p](int a)->int {return a * p; };
    
        //fun(f);//error
        fun2(f);
    }
    
    void useLambdaAsFunPtr2()
    {
        int p = 7;
        static auto f = [p](int a)->int {return a * p; };
        MYPROC ff = [](int i)->int { return f(i); };
        //here, it works!
        fun(ff);
    }
    
    void test()
    {
        useLambdaAsFunPtr2();
    }
    
    typedef int(*MYPROC)(int);
    虚无乐趣(MYPROC m)
    {
    
    一个更简洁的解决方案是将lambda封装在适配器中,假设函数指针有一个上下文参数。@RaymondChen:好吧,如果您可以自由定义函数的使用方式,那么是的,这是一个选项。不过在这种情况下,只需将参数作为lambda本身的参数就更容易了!@KerrekSB-put
    名称空间中的全局变量
    ,并将它们标记为
    thread\u local
    ,这是我为解决类似问题而选择的
    ftw
    方法。“函数指针指向单个全局函数,而此信息没有空间容纳状态。”->像Java这样的语言怎么能做到这一点呢?当然,因为单个全局函数是在运行时创建的,并嵌入状态(或者更确切地说是对状态的引用)在它自己的代码中,这就是整个点——不应该有一个单一的全局函数,而是多个全局函数——每次运行时使用lambda。一个C++中真的没有什么可以做到吗?(我认为STD:函数是为那个目的而精确地制作的)答案是否定的,长的答案涉及操作符重载。不管怎样,我的观点是:java是一种不同于C++的语言;java没有指针(或者可重载的调用操作符),而且比较不太好。
    auto f2 = Lambda::ptr(b);
    f2(nullptr);
    printf("%d\n", a); // 102
    
    int (*f3)(void*) = Lambda::ptr<int>(b);
    printf("%d\n", f3(nullptr)); // 103
    
    auto b2 = [&](void* data) {return *(int*)(data) + a;};
    int (*f4)(void*) = Lambda::ptr<int>(b2);
    int data = 5;
    printf("%d\n", f4(&data)); // 108
    
    template <class F>
    auto cify_no_args(F&& f) {
      static F fn = std::forward<F>(f);
      return [] {
        return fn();
      };
    }
    
    void some_c_func(void (*callback)());
    
    some_c_func(cify_no_args([&] {
      // code
    }));
    
    template <class F>
    struct lambda_traits : lambda_traits<decltype(&F::operator())>
    { };
    
    template <typename F, typename R, typename... Args>
    struct lambda_traits<R(F::*)(Args...)> : lambda_traits<R(F::*)(Args...) const>
    { };
    
    template <class F, class R, class... Args>
    struct lambda_traits<R(F::*)(Args...) const> {
        using pointer = typename std::add_pointer<R(Args...)>::type;
    
        static pointer cify(F&& f) {
            static F fn = std::forward<F>(f);
            return [](Args... args) {
                return fn(std::forward<Args>(args)...);
            };
        }
    };
    
    template <class F>
    inline lambda_traits<F>::pointer cify(F&& f) {
        return lambda_traits<F>::cify(std::forward<F>(f));
    }
    
    void some_c_func(int (*callback)(some_struct*, float));
    
    some_c_func(cify([&](some_struct* s, float f) {
        // making use of "s" and "f"
        return 0;
    }));
    
    typedef int (* MYPROC)(int);
    
    void fun(MYPROC m)
    {
        cout << m(100) << endl;
    }
    
    template<class T>
    void fun2(T f)
    {
        cout << f(100) << endl;
    }
    
    void useLambdaAsFunPtr()
    {
        int p = 7;
        auto f = [p](int a)->int {return a * p; };
    
        //fun(f);//error
        fun2(f);
    }
    
    void useLambdaAsFunPtr2()
    {
        int p = 7;
        static auto f = [p](int a)->int {return a * p; };
        MYPROC ff = [](int i)->int { return f(i); };
        //here, it works!
        fun(ff);
    }
    
    void test()
    {
        useLambdaAsFunPtr2();
    }