Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize once_flag?

Tags:

c++

c++11

What is a once_flagsupposed to be initialized to? I've tried false and 0, and both have given errors similar to below (below is 0):

no viable conversion from 'int' to 'std::once_flag'

Here's how I am trying to use it. (I consider it bad style to not initialize statics even though the language initializes them, so I'd really prefer to have something there).

MyClass& GetMyClass()
{
    static std::once_flag flag;
    static MyClass cls;

    std::call_once(flag, []() {
        // Initialize class
    });

    return cls;
}
like image 694
jww Avatar asked Nov 15 '13 02:11

jww


4 Answers

Update

If we look at the draft C++ standard section 30.4.4.1 Struct once_flag we can see the constructor is defined as:

constexpr once_flag() noexcept;

since it is a constexpr your static instance will be statically initialized and we can see an example in section 30.4.4.2 Function call_once that uses a static instance:

void g() {
 static std::once_flag flag2;
 std::call_once(flag2, initializer());
}

Original

If we look at the documentation to std::once_flag it says:

once_flag();

Cnstructs an once_flag object. The internal state is set to indicate that no function
has been called yet. 

and if we look further at the document documentation for call_once we see the following example which demonstrates how to use std::once_flag:

#include <iostream>
#include <thread>
#include <mutex>

std::once_flag flag; 

void do_once()
{
    std::call_once(flag, [](){ std::cout << "Called once" << std::endl; });
}

int main()
{
    std::thread t1(do_once);
    std::thread t2(do_once);
    std::thread t3(do_once);
    std::thread t4(do_once);

    t1.join();
    t2.join();
    t3.join();
    t4.join();
}

with the following expected output:

Called once
like image 119
Shafik Yaghmour Avatar answered Nov 17 '22 17:11

Shafik Yaghmour


Since your question has been answered elsewhere, as an alternative to the code you posted, you can also do this instead:

// private function in anonymous namespace or something
MyClass& initMyClass() {
    static MyClass c;
    /* initialize c */
    return c;
}

and then have clients call

MyClass& GetMyClass() {
    static MyClass& c = initMyClass();
    return c;
}

because static initializations are thread safe now in C++11. And then you don't have to mess with call_once or anything.

like image 20
uk4321 Avatar answered Nov 17 '22 17:11

uk4321


what are you trying to do? you cannot initialize std::once_flag with any value because it only has one constructor that does not take any arguments.

http://en.cppreference.com/w/cpp/thread/once_flag

once_flag(); Constructs an once_flag object. The internal state is set to indicate that no function has been called yet.

BTW, what is the reason that you consider not initialize statics variable is a bad style?

like image 27
Bryan Chen Avatar answered Nov 17 '22 15:11

Bryan Chen


ONCE_FLAG_INIT

EDIT: C only, not C++. Defined in <threads.h>.

like image 34
Pete Becker Avatar answered Nov 17 '22 17:11

Pete Becker