我已经在多线程上下文中测试了 call_once ()与变量的使用,并且行为符合预期。
但是,在多线程上下文中,我很难让 call_once ()与构造函数一起正常工作。
为此编写了以下program。它是Stroustrup在“CPL”第4版中提供的示例的修改。
/**
initialize_once_class_ctor.cpp
Demonstrate the use of the once_flag type and the call_once() function
to implement lazy initialization of a class' constructor.
**/
#include <mutex> // once_flag, call_once()
#include <thread> // thread
#include <iostream> // cout
using namespace std;
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 ...
/// implementation ...
int main()
{
thread t1 {X::X};
thread t2 {X::X};
t1.join();
t2.join();
}
该程序会出现编译错误:
main.cpp: In function 'int main()':
main.cpp:57:19: error: no matching function for call to 'std::thread::thread(<brace-enclosed initializer list>)'
thread t1 {X::X};
^
In file included from main.cpp:10:
/usr/local/include/c++/8.1.0/thread:118:7: note: candidate: 'template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...)'
thread(_Callable&& __f, _Args&&... __args)
^~~~~~
/usr/local/include/c++/8.1.0/thread:118:7: note: template argument deduction/substitution failed:
main.cpp:57:19: note: couldn't deduce template parameter '_Callable'
thread t1 {X::X};
^
In file included from main.cpp:10:
/usr/local/include/c++/8.1.0/thread:113:5: note: candidate: 'std::thread::thread(std::thread&&)'
thread(thread&& __t) noexcept
^~~~~~
/usr/local/include/c++/8.1.0/thread:113:5: note: no known conversion for argument 1 from '<unresolved overloaded function type>' to 'std::thread&&'
/usr/local/include/c++/8.1.0/thread:106:5: note: candidate: 'std::thread::thread()'
thread() noexcept = default;
^~~~~~
/usr/local/include/c++/8.1.0/thread:106:5: note: candidate expects 0 arguments, 1 provided
main.cpp:58:19: error: no matching function for call to 'std::thread::thread(<brace-enclosed initializer list>)'
thread t2 {X::X};
^
In file included from main.cpp:10:
/usr/local/include/c++/8.1.0/thread:118:7: note: candidate: 'template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...)'
thread(_Callable&& __f, _Args&&... __args)
^~~~~~
/usr/local/include/c++/8.1.0/thread:118:7: note: template argument deduction/substitution failed:
main.cpp:58:19: note: couldn't deduce template parameter '_Callable'
thread t2 {X::X};
^
In file included from main.cpp:10:
/usr/local/include/c++/8.1.0/thread:113:5: note: candidate: 'std::thread::thread(std::thread&&)'
thread(thread&& __t) noexcept
^~~~~~
/usr/local/include/c++/8.1.0/thread:113:5: note: no known conversion for argument 1 from '<unresolved overloaded function type>' to 'std::thread&&'
/usr/local/include/c++/8.1.0/thread:106:5: note: candidate: 'std::thread::thread()'
thread() noexcept = default;
^~~~~~
/usr/local/include/c++/8.1.0/thread:106:5: note: candidate expects 0 arguments, 1 provided
如何修复这些编译错误?
答案 0 :(得分:2)
永远不能直接调用构造函数(作为函数)。打字,例如X{}
或X()
是用于创建X
类型的(临时)对象,而不是以调用X
的构造函数的语法。构造函数作为创建对象的一部分被调用,但那是内部的。
std::thread
需要一个可调用的,而构造函数永远不能是一个。你可以提供一个lambda:
auto f = []{ X{}; };
thread t1 {f};
thread t2 {f};