I want to execute a function at periodic interval that takes an object as argument.
I tried this answer: https://stackoverflow.com/a/72226772/13798537 that calls a function at periodic interval which takes an integer as argument, but I couldn't figure out how to call a function at periodic interval that takes an object as argument.
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <memory>
#include <atomic>
#include "window.h" // Contains the declaration of Window class
using cancel_token_t = std::atomic_bool;
template<typename Fnc>
void set_interval(Fnc fun, std::chrono::steady_clock::duration interval,
std::shared_ptr<cancel_token_t> cancel_token=nullptr)
{
std::thread([fun=std::move(fun), interval, tok=std::move(cancel_token)]()
{
while (!tok || !*tok) // Call until token becomes true (if it is set)
{
auto next = std::chrono::steady_clock::now() interval;
fun();
std::this_thread::sleep_until(next);
}
}).detach();
}
void foo(Window &window)
{
// Do something with the window object
}
int main()
{
Window window;
using namespace std::chrono_literals;
auto cancel = std::make_shared<cancel_token_t>(false);
// Ordinary rules for lambda capture apply so be careful
// about lifetime if captured by reference.
set_interval([window]
{
foo(window);
}, 1000ms, cancel);
//set_interval([window]{foo(window);}, 1000ms); // Without token, runs until main exits.
std::this_thread::sleep_for(3s);
*cancel = true;
}
I get the following error when I compile:
'void foo(Window &)': cannot convert argument 1 from 'const Window' to 'Window &'
How can I achieve this?
Thanks.
CodePudding user response:
operator()
of non-mutable lambda is const
.
As you capture by copy, you cannot then mutate your captured "member".
You probably want to capture by reference instead:
set_interval([&window] { foo(window); }, 1000ms, cancel);
or if you really want copy, make the lambda mutable
:
set_interval([window] mutable { foo(window); }, 1000ms, cancel);