c++ 如果std::call_once已执行,获取状态?

bttbmeg0  于 2023-08-09  发布在  其他
关注(0)|答案(1)|浏览(88)

我正在开发一个C++库,它允许我只为POD设置一次值(类似于flutter的final关键字)。
在我的应用程序中,有几个配置只设置一次(在初始化期间),并且在程序的生命周期内保持有效。
我使用std::oncestd::call_once来实现相同的功能。
我遇到了一个障碍,无法检查std::call_once是否已执行。
我想添加std::atomic_bool来跟踪std::call_once的状态。
我想知道他们是否是一个比布尔标志更好的替代品,我可以使用相关的std::once_flag对象来获取std::call_once执行的状态。
代码:

#pragma once
#include <mutex>

class DataNotSetException: public std::exception
{
public:
    const char* message = "Data Not Set before Get Operation";
    char* what()
    {
        return const_cast<char *>(this->message);
    }
};

template<typename T>
class SetOnce
{
private:
    T data;
    std::once_flag flag;
    void do_once(const T& data);
public:
    T get(void) const;
    void set(const T& data);
    bool is_set(void) const;

};

template<typename T>
inline void SetOnce<T>::do_once(const T& data)
{
    this->data = data;
}

//If data is not been set throw data not set exception (DataNotSetException)
template<typename T>
inline T SetOnce<T>::get(void) const
{
    if (this->is_set() == true)
    {
        return this->data;
    }
    else
    {
        throw DataNotSetException();
    }
}

template<typename T>
inline void SetOnce<T>::set(const T& data)
{
    std::call_once(this->flag, this->do_once, data);
}

template<typename T>
inline bool SetOnce<T>::is_set(void) const
{
    //How to check if the call_once has been executed
}

字符串
编辑
我在一个实时系统上工作,因此希望避免在get操作上延迟相关的阻塞(忙等待)互斥调用。
get操作预期具有较低的响应时间和较高的执行频率。

dfty9e19

dfty9e191#

它不是那么漂亮,但你可以使用std::call_once本身来执行检查:

bool check_once(std::once_flag& flag)
{
    try{
        std::call_once(flag,[](){throw 42;});
        return true;
    }
    catch(const int&){
        return false;
    }
}

字符串

  • 如果之前已经调用了一个函数,那么这个调用什么也不做-> true被返回。
  • 如果之前没有调用函数,我们的函数会被调用并无条件抛出,这确保了标志不会被设置,并且预期的调用仍然可以在以后发生。

就我个人而言,我会选择在通话结束时设置的自定义std::atomic_bool

相关问题