【问题标题】:"lambda capture" on regular function?常规功能上的“lambda捕获”?
【发布时间】:2020-06-06 11:13:55
【问题描述】:
 void startDrawLoop(function<bool()> func)
        {
        while (func()) {} 
        }

    int main() 
    {
    CubeRenderer cubeRenderer; TextRenderer textRenderer;

    // Do initialization

    auto drawLoop=[&] () 
    {
    cubeRenderer.draw();
    textRenderer.draw();
    return true;
    } 
    startDrawLoop(drawLoop);
    return 0;
    } 

如果我将drawLoop 更改为函数。

bool drawLoop()
{
// Error, cannot find cubeRenderer
cubeRenderer.draw();
textRenderer.draw();
return true;
} 

如何像 lambda 捕获一样引用函数外部的变量?

【问题讨论】:

    标签: c++ c++11 lambda


    【解决方案1】:

    您可以让drawLoop 接受参数并从执行捕获的 lambda 调用它。

    void startDrawLoop(function<bool()> func)
    {
        while (func()) {}
    }
    
    bool drawLoop(CubeRenderer const& cubeRenderer, TextRenderer const& textRenderer)
    {
        cubeRenderer.draw();
        textRenderer.draw();
        return true;
    }
    
    int main()
    {
        CubeRenderer cubeRenderer; TextRenderer textRenderer;
        startDrawLoop([&]() { drawLoop(cubeRenderer, textRenderer); });
    }
    

    您也可以使用std::bind,但我个人觉得它与 lambda 相比很难看。

    startDrawLoop(std::bind(drawLoop, std::cref(cubeRenderer), std::cref(textRenderer));
    

    如果您想让调用站点尽可能简单,您可以将startDrawLoop 设为模板以接受带有任何参数的任何函数。

    template<typename F, typename... Args>
    void startDrawLoop(F func, Args const&... args)
    // [...]
    startDrawLoop(drawLoop, cubeRenderer, textRenderer);
    

    Demo

    【讨论】:

    • 谢谢!它完美地工作。我只是想知道是否有摆脱 lambda 的方法。使用起来不是很直观,因为std::function 理想情况下应该接受任何可调用类型。
    • 当然,但它变得有点复杂。已编辑。
    【解决方案2】:

    没有 lambda 的等效代码是:

    struct lambda_t
    {
        CubeRenderer &cubeRenderer;
        TextRenderer &textRenderer;
    
        bool operator()() const
        { 
            cubeRenderer.draw();
            textRenderer.draw();
            return true;
        }
    };
    
    
    int main() 
    {
        CubeRenderer cubeRenderer; TextRenderer textRenderer;
        lambda_t drawLoop{cubeRenderer, textRenderer};
        startDrawLoop(drawLoop);
        return 0;
    } 
    

    这是否更美观取决于你......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-05
      • 2016-03-10
      • 1970-01-01
      • 2017-06-14
      • 2013-04-20
      • 1970-01-01
      • 2016-10-15
      • 1970-01-01
      相关资源
      最近更新 更多