почему функтор должен быть помещен в скобки при передаче в коструктор потока?

#multithreading #c 11 #syntax #most-vexing-parse

#многопоточность #c 11 #синтаксис #самый неприятный синтаксический анализ

Вопрос:

 #include <iostream>
#include <thread>
class DisplayThread
{
public:
    void operator()()     
    {
        for(int i = 0; i < 10000; i  )
            std::cout<<"Display Thread Executing"<<std::endl;
    }
};
 
int main()  
{
   //line 1:
    std::thread threadObj( (DisplayThread()) );
    for(int i = 0; i < 10000; i  )
        std::cout<<"Display From Main Thread "<<std::endl;
    std::cout<<"Waiting For Thread to complete"<<std::endl;
    threadObj.join();
    std::cout<<"Exiting from Main Thread"<<std::endl;
    return 0;
}
    
  

В строке 1: если я использую что-то вроде «threadObj(DisplayThread())», это дает
ошибка, указывающая на отсутствие типа класса.

Может кто-нибудь сказать мне, почему функтор при передаче в конструктор потока должен быть внутри фигурных скобок «()»?

Комментарии:

1. std::thread threadObj(testObj()); вызывает DisplayThread::operator()() . Я думаю, вы хотите, чтобы поток вызывал его вместо этого.

Ответ №1:

Поздравляю … в некотором роде: вы стали жертвой явления C , известного как самый неприятный синтаксический анализ: в основном, тенденция компилятора интерпретировать ваши утверждения как объявления функций. Вы не виноваты — это результат двусмысленности в языке, который, оказывается, решается несколько неинтуитивным способом.

Ошибка, которую вы получаете, когда вы удаляете круглые скобки вокруг DisplayThread() , является:

 <source>: In function 'int main()':

<source>:20:15: error: request for member 'join' in 'threadObj', which is of 
non-class type 'std::thread(DisplayThread (*)())'
   20 |     threadObj.join();
      |               ^~~~
  

Компилятор считает, что threadObj это функция, которая принимает указатель на функцию и возвращает std::thread !

Это решается, если вы используете фигурные скобки для построения без аргументов, например:

 std::thread threadObj{ DisplayThread{} };
  

Комментарии:

1. спасибо за ответ. Не знал об этом явлении. Сегодня узнал кое-что новое.

2. @StraightCirle: Конечно, вы не знали об этом, вот почему поначалу это всех раздражает