【问题标题】:Trying to return a function from a function with an argument function within it试图从一个带有参数函数的函数返回一个函数
【发布时间】:2021-10-03 11:04:26
【问题描述】:

我很好奇是否可以在另一个函数中创建一个静态函数,然后返回该静态函数,其中包含一个参数函数。到目前为止,我尝试过的根本不起作用,当我使用原始函数指针时,代码无法编译。

#include <iostream>
#include <functional>

//both do not work but this one doesn't even compile
/*
void (*func(void (*foo)()))()
{
    static void (*copy)();
    copy = [&]() { foo(); };
    return copy;
}
*/

std::function<void(void)> Foo(std::function<void(void)> func)
{
    static std::function<void(void)> temp = [&]() { func(); };
    return temp;
}

int main()
{
    Foo([]() { std::cout << 123 << '\n'; });
}

【问题讨论】:

    标签: c++ function function-pointers


    【解决方案1】:

    您评论的func 的问题是捕获任何内容的 lambda 无法转换为指向函数的指针。 Lambda 捕获提供在初始化时保存的数据,以便在调用时使用,而普通 C++ 函数除了传递的参数之外没有任何数据。这种能力实际上是std::function 有用的重要原因之一,我们不只是使用函数指针来完成它的工作。 std::function 比函数指针更强大。

    当然,func 可以改为 copy = foo;或者只是 return foo;,避免 lambda 问题。

    Foo 的一个问题是 lambda 通过引用捕获函数参数func,然后在Foo 返回并且func 的生命周期结束后调用。可能在其捕获范围结束后调用的 lambda 不应该通过引用来捕获它们,std::function 是进入这种糟糕情况的一种简单方法。 lambda 应该改用[=][func]

    请注意,Foo 中的 static 与实际函数声明前的 static 不同。它使temp 成为一个函数静态变量,它只在第一次初始化然后保存。如果 Foo 用不同的 lambda 第二次调用,它将返回与第一次相同的内容。如果这不是您想要的,请删除 static。函数/变量的链接在这里不是问题。

    (有点奇怪,Foostd::function 放入 std::function 内的 lambda 内,所有这些都直接调用下一个,而不是仅使用原始的 std::function。但我假设这只是因为它是一个简化的或仅供学习的示例。如果 lambda 做了一些额外的或不同的事情,这将是一个很好的方法。)

    您的main 忽略了从Foo 返回的函数。也许你的意思是调用 Foo 返回的内容,用

    int main()
    {
        Foo([]() { std::cout << 123 << '\n'; })();
    }
    

    【讨论】:

    • 非常丰富的答案。谢谢
    【解决方案2】:

    它可以工作,你永远不会调用函数:

    #include <iostream>
    #include <functional>
    
    std::function<void(void)> Foo(std::function<void(void)> func)
    {
        static std::function<void(void)> temp = [&]() { func(); };
        return temp;
    }
    
    int main()
    {
        // Notice final `()`
        Foo([]() { std::cout << 123 << '\n'; })();
    }
    

    但是您是通过引用捕获函数,因此您必须确保捕获器不会超过它。 否则你可以复制捕获它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多