标准库函数,仅运行一次函数

时间:2014-08-26 07:33:42

标签: c++ c++11 lambda c++14

这个lambda表达式的行为是否有一些标准的库函数/类:

void some_func(int some_arg, float some_other_arg){
    static int do_once = ([](){
        // will be run once upon first function call but never again
        return 0; // dummy return value
    })();
    // will always run
}

写这个就好像是一个黑客,但除了简单地调用main中的函数之外,我无法想到另一种方法,但我实际上在做什么取决于在模板参数上,我需要尽可能保持通用。

上下文:
我为每个不同的模板参数注册一个带atexit的函数,但只注册一次:第一次调用它。

3 个答案:

答案 0 :(得分:14)

也许您应该使用std::call_once中的<mutex>
如何使用它的示例here

答案 1 :(得分:1)

我选择std::call_once选项,效果很好。

为此,我重写了我的功能:

template<typename T>
void my_function(){
    static std::once_flag once;

    // function body (may return)

    // only called if rest of function successful
    std::call_once(once, [](){/* special sauce */});
}

@cdhowie,我不认为你完全理解static的意思,它几乎与全球的相反。

答案 2 :(得分:0)

正如评论中所建议的那样,std::call_once()是一个选项,但即使你提供了不同的模板参数,你也无法使std::once_flag全局或只有一个函数被调用。听起来你只想为给定的模板参数调用一次函数。

如果是这种情况,那么你可以使该函数成为模板类的静态部分,同时仍然使用std::call_once()机制:

template <typename T>
class initializer
{
public:
    static void call();

private:
    static void target();

private:
    static std::once_flag flag;
};

template <typename T>
void initializer<T>::call()
{
    std::call_once(flag, target);
}

template <typename T>
void initializer<T>::target()
{
    // Your code goes here.
}

template <typename T>
std::once_flag initializer<T>::flag;

现在,您可以使用不同的initializer<T>::call()类型来呼叫T,并确保每个不同的T只能拨打一个电话。