Cas*_*sey 4 c++ c++17 std-call-once
我不久前根据虚幻引擎 4 的蓝图实现编写了一个函数,该函数仅调用一次可调用函数,直到它被重置:
template<typename Callable>
void DoOnce(Callable&& f, bool reset = false, bool start_closed = false) noexcept {
static bool once = start_closed;
if(!once) {
once = true;
std::invoke(f);
}
if(reset) {
once = false;
}
}
Run Code Online (Sandbox Code Playgroud)
今天我了解到std::call_once存在,跨线程工作,使用带有参数的可调用对象,测试异常安全,并且基本上std::invoke像我一样进行包装(至少是 MSVC 实现)。
这听起来很棒,而且在可能的情况下,我更喜欢调用预先存在的函数而不是编写自己的函数。
就像虚幻的文档所暗示的那样,有时我可能需要通过重置内部标志来再次调用可调用对象;可以std::call_once重置以允许再次调用底层可调用对象吗?
当标准将其称为“once_flag”时,它并不是在开玩笑。这是一个只设置一次的标志。
当然,您可以使用不同的一次标志对象多次调用该函数。但要正确执行此操作,您需要将可能尝试调用新的一次标志对象的每个线程交给它。它不能只是某处的全局或静态对象;它还可以是全局或静态对象。您必须实际将每个新调用编组到所有想要调用它的线程。