1
 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;
    } 

If I change drawLoop to a function.

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

How can I make reference to variables outside the function like what lambda captures do?

2 Answers 2

3

You can just make drawLoop accept arguments and call it from a lambda that does the capture.

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); });
}

You can also use std::bind but I personally find it ugly compared to the lambda.

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

If you want to make the call site as simple as possible, you can make startDrawLoop a template to accept any function with any arguments.

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

Demo

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! It works perfectly. I am just wondering if there is a walkaround to get rid of the lambda. It's not very intuitive to use, since std::function ideally should accept any callable type.
Sure but it gets a bit more complex. Edited.
1

The equivalent code without the lambda is:

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;
} 

Whether this is more aesthetic or not is up to you...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.