Reputation: 59
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?
Upvotes: 1
Views: 148
Reputation: 141554
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...
Upvotes: 1
Reputation: 13269
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);
Upvotes: 3