【问题标题】:Can std::call_once be reset?可以重置 std::call_once 吗?
【发布时间】:2021-04-28 03:08:32
【问题描述】:

我不久前编写了一个基于Unreal Engine 4's blueprint implementation 的函数,它只调用一次可调用对象,直到它被重置:

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

今天我了解到std::call_once 的存在,跨线程工作,使用有参数的可调用对象,测试异常安全性,并且基本上像我的一样环绕std::invoke(至少是MSVC 实现)。

这听起来很棒,而且,如果可能的话,我更喜欢调用预先存在的函数而不是编写自己的函数。

就像 Unreal 的文档所暗示的那样,有时我可能需要通过重置内部标志来再次调用可调用对象; 可以重置 std::call_once 以允许再次调用底层可调用对象吗?

【问题讨论】:

  • 好吧,您可以通过使用 placement-new 创建一个新标志来重置标志。我在标准中没有看到任何可以排除这种可能性的东西,尽管它闻起来有点腥

标签: c++ c++17 std-call-once


【解决方案1】:

当他们称其为“once_flag”时,该标准并不是在开玩笑。这是一个只会设置一次的标志。

您当然可以使用 不同 一次标志对象多次调用该函数。但是要正确地做到这一点,您需要处理每个可能试图将其称为新的一次性标志对象的线程。它不能只是某个地方的全局或静态对象;您必须将每个新调用实际编组到所有想要调用它的线程。

【讨论】:

  • @Casey:嗯,你是试图call_once 一件事不止一次的人。粗略是意料之中的;)
  • 调用一次看起来像标准向我公开的“神奇的静态,但没有静态”。就像,static const bool unused=(static_cast&lt;void&gt;(f()),true); 没有噪音。
  • 我接受这个作为答案,但理解这是一种冗长的说法:“不,这不是它的用途。” :) 不当使用 STL 或标准会招致灾难。
猜你喜欢
  • 2014-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
相关资源
最近更新 更多