【问题标题】:Why my C++ program crash when convert lambda to function pointer为什么我的 C++ 程序在将 lambda 转换为函数指针时崩溃
【发布时间】:2016-02-22 10:57:25
【问题描述】:

我尝试将 lambda 函数转换为函数指针,编译正常,但运行时崩溃(VC2013)。这个 lambda 函数只是删除一个指针,像这样:

typedef void(*pf)(void*);
struct M
{
    ~M(){ printf("dtor\n"); }
};
int main(void)
{
    M *p = new M;
    auto f = [](M*p){delete p; };
    pf p1 = (pf)&f;
    (*p1)(p);
    return 0;
}

[/代码]

崩溃似乎发生在 CRT 内部,无法自行调试。我的崩溃是从哪里来的?非常感谢

【问题讨论】:

  • (pf)&f; 是危险的,为了确保可以安全地执行转换,请使用static_cast。使用它你会得到错误,基本上说f 的类型不是指向函数的指针。 => 未定义的行为
  • 除非您知道自己在做什么,否则不要强制转换:警告:ISO C++ 禁止在指向函数的指针和指向对象的指针之间强制转换 [-Wpedantic]
  • 为什么要使用函数指针? C++11 提供了许多其他方式来存储指向可调用对象的指针
  • “我试图将 lambda 函数转换为函数指针”:不,您尝试将 pointer 转换为 lambda 函数为函数指针。 (当编译器说你不能时,你没有听,而是插入了一个演员表。)

标签: c++ function pointers lambda crash


【解决方案1】:

有几个问题:

  1. 非捕获 lambda 可以转换为函数指针,指向 lambda 的指针不能。摆脱地址运算符。
  2. lambda 表示的函数类型是void(*)(M*)pfvoid(*)(void*)。它们不兼容!要么让 lambda 采用 void*,要么将 fp 改为采用 M* 参数。
  3. C-casts 默默地做错事。如果其他一切都正确,则不需要一个,隐式转换就足够了。

以下代码将起作用:

#include <cstdio>

struct M
{
    ~M(){ printf("dtor\n"); }
};

typedef void(*pf)(M*);

int main(void)
{
    M *p = new M;
    auto f = [](M*p){delete p; };
    pf p1 = f;
    (*p1)(p);
    return 0;
}

【讨论】:

    【解决方案2】:

    通过void* 删除对象会给你带来麻烦。

    1. 将参数类型更改为 f 为 void f(M*)
    2. 不要写这样的代码,它最终会得到你

    这是适用于 gcc 4.8 的代码

    #include <cstdio>
    
    class M; //forward dec
    typedef void(*pf)(M*);
    
    struct M
    {
        ~M(){ printf("dtor\n"); }
    };
    
    
    
    int main(void)
    {
        M *p = new M;
        auto f = [](M*p){delete p; };
        pf p1 = f;
        (*p1)(p);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-26
      • 2018-10-29
      • 2018-06-15
      • 2020-05-12
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 1970-01-01
      相关资源
      最近更新 更多