为什么编译函子需要额外的括号"std::thread"?

Why extra parenthesis is needed to compile "std::thread" functor?

本文关键字:std thread 编译 为什么      更新时间:2023-10-16

我正在从"古代" C 移动到较新的C 11,并查看std::thread库。

class MyThread
{
public:
    int i = 0;
    void operator()()
    {
        for (;i < 10000; i++)
            cout << "Exectuing " << endl;
    }
};

main()中,我有以下行:

thread threadObj( MyThread() );
for (int i = 0; i < 1; i++)
    cout << "Main thread " << endl;
threadObj.join();

它不会编译最后一行:"表达式必须具有类型"

thread threadObj( (MyThread()) );添加额外的括号解决了问题。

为什么?类型保持不变:thread

我是否错过了一些新的C 11功能?还是我只是困惑...

您看到的问题被称为最烦人的解析:https://en.wikipedia.org/wiki/wiki/most_vexing_parse_parse

出于C 11的原因,您可以使用新的'{}'进行初始化。

使用新表格可以写:

thread threadObj{ MyThread{} };

这将使用一个空的初始化器列表和线程对象本身创建MyThread,并使用MyThread{}初始化创建的对象。

使用以下表格:thread threadObj( MyThread() );是怎么回事?编译器将其解释为函数调用,而不是对象的初始化。因此,使用新的{}表单可以使编译器清楚。

如果您在程序中使用{},则应严格使用它。使用它:

thread threadObj{ MyThread() }; // bad style!

看起来有些神秘,因为您在旧版本和新版本中使用。从技术上讲,这有效,但使代码不可读。(至少对于我的眼睛:-)(

我是否错过了一些新的C 11功能?或只是困惑。

是,在C 11中,您使用通用初始化器。更改代码

的行
thread threadObj( MyThread() );

AS

 thread threadObj{ MyThread() };

它将正常工作