【问题标题】:How can I make a function pointer that references a local variable?如何创建引用局部变量的函数指针?
【发布时间】:2015-10-12 23:30:04
【问题描述】:

我正在尝试使用第一个列表的 forEach 方法将一个列表中的所有项目添加到另一个列表中,该方法接受一个函数指针并在每个元素上调用该函数,但是我无法创建一个可以调用的函数指针第二个列表的成员函数。我尝试过使用 lambda:

LinearLinkedList<bar> test;
//<add items to test>
LinearLinkedList<bar> sorted;
auto addToSorted = [&](bar * b) { sorted.addSorted(b, &barLessThan); };
test.forEach(&addToSorted);

并使用内部struct:

LinearLinkedList<bar> test;
//<add items to test>
LinearLinkedList<bar> sorted;
struct Sorter {
    static LinearLinkedList<bar> * list = &sorted;
    static void addToSorted(bar * b) { list->addSorted(b, &barLessThan); }
};
test.forEach(&Sorter::addToSorted);

但两者都被编译器拒绝,因为它们以非法方式引用 sorted。如何在调用forEach 时引用sorted

【问题讨论】:

标签: c++ lambda closures function-pointers


【解决方案1】:

只有在不捕获任何内容时,Lambda 才能衰减为函数指针。考虑以下 sn-p:

#include <iostream>

void run(int(*f)())
{
    std::cout << f();
}

struct S {
    static int something;
    static int nothing()
    {
        return something;
    }
};
int S::something = 0;

int main()
{
    auto simpleLambda = [](){ return 1; };
    run(simpleLambda);

    // auto capturingLambda = [&](){ return 1; };
    // run(capturingLambda);

    S::something = 2;
    run(S::nothing);
}

注释掉的部分不会编译,因为capturingLambda 有一个非空的捕获列表。您可以使用我在代码中添加的解决方法,或者更好地将您的 forEach 函数模板化为仿函数类型,就像所有 STL 算法一样。

【讨论】:

  • 这个问题不一定是关于 lambdas 的。这里的教训是函数指针无法引用非全局变量吗?
  • @Saposhiente 我明白了。好吧,如果您考虑一下,函数指针只能访问其参数和具有静态存储持续时间的数据。因此,除非您将本地数据放入其中任何一个,否则该函数(通过函数指针访问)将无法访问它。 Here 有一种更简洁的解决方法,但想法仍然相同,您无法从免费函数中访问非静态存储持续时间数据。
猜你喜欢
  • 2021-11-26
  • 1970-01-01
  • 2019-11-07
  • 2020-10-13
  • 2021-11-11
  • 1970-01-01
  • 2023-04-09
  • 2011-06-02
相关资源
最近更新 更多