Reputation: 753
The following program tries to use call_once() in a constructor. It is a modification of an example provided by Stroustrup in "CPL", 4.
class X
{
private:
static int data;
static once_flag initdata_flg;
static void init();
public:
X()
{
call_once(initdata_flg, init);
cout << "** diagnostic: X::data initialized"
<< endl;
}
int getdata() const
{
return data;
}
};
/** class X static members ...
(static members must be defined
outside the class **/
int X::data;
once_flag X::initdata_flg;
void X::init()
{
data = 915;
}
/// declarations ...
void construct();
/// implementation ...
int main()
{
thread t1 {construct};
thread t2 {construct};
t1.join();
t2.join();
}
void construct()
{
X x;
}
The output is as follows:
** diagnostic: X::data initialized
** diagnostic: X::data initialized
The diagnostic appears twice, rather than once. Clearly, this is not how to use call_once() correctly in a constructor.
For this to work, I would need to use call_once() in the construct() function. That's not what I want to do. I want to use call_once() in the constructor.
What is the right way to do so?
Upvotes: 0
Views: 185
Reputation: 171097
You're issuing the diagnostic in the consturctor, not in init
. Of course the constructor will run twice; it will always run once for each object you create. However, only one of the calls to call_once
will actually call init
, which you can verify by moving the diagnostic output there.
Upvotes: 4