CodeInside
@CodeInside

Как исправить ошибку 'сбой при специализации функции-шаблона' (многопоточность)?

Сам проект большой, поэтому выложу фрагменты, которые связаны с потоками.
// В объявлении первого класса
private:
std::thread	firstClassThread;
int run();

// Конструктор данного класса
FirstClass::FirstClass() : /* список инициализаторов */ firstClassThread(run()) { }

// Использование потока
switch (received_data) {
	case FIRST_CONST:
		// ...
		firstClassThread.detach();
		break;

	case SECOND_CONST:
		if (/* logical condition */) {
			// ...
			SuspendThread(firstClassThread.native_handle());
		}
		else if (/* logical condition */) {
			// ...
			ResumeThread(firstClassThread.native_handle());
		}
		break;
}

// Второй класс, объекты которого агрегирует в себе FirstClass
// в объявлении
private:
int someFunc(const int& data);

// В одном из публичных методов этого второго класса
std::thread someFuncThread(someFunc(data), data);
	someFuncThread.detach();
	Sleep(duration);


В итоге я получаю вот такие две ошибки:
  1. "std::invoke": не найдена соответствующая перегруженная функция
  2. Сбой при специализации функции-шаблона "unknown-type std::invoke(_Callable &&,_Types &&...)"


Первый раз работаю с многопоточностью. Можете помочь исправить данные ошибки?
  • Вопрос задан
  • 1918 просмотров
Решения вопроса 2
Всё становится проще с лямбдами:

// Было
std::thread someFuncThread(someFunc(data), data);
// Стало
std::thread someFuncThread([this, data] { return this->someFunc(data); });

Аналогично будет в другом месте. Помните:
  1. this тоже надо захватывать, и этого не избежать вызовом метода без this, то есть как someFunc(data)
  2. Это ваши проблемы следить за тем, что на момент вызова объект *this "жив"
  3. data здесь захватывается по значению. Если объём данных большой, и вы можете гарантировать их время жизни, то захватите по ссылке: [this, &data]

Upd Как отложить запуск:
std::thread someFuncThread;
//...
someFuncThread = std::thread( создаём_как_показано_выше );
Ответ написан
@MarkusD Куратор тега C++
все время мелю чепуху :)
en.cppreference.com/w/cpp/thread/thread/thread

int run(); // Имеет тип `int (FirstClass::*)()`. А конструктору `std::thread` нужен или функтор, или глобальная функция.


Перепиши `run()` на статическую и передавай инстанцию объекта `FirstClass` параметром при запуске.
иное решение - использовать лямбду с замыканием на this.
FirstClass::FirstClass() : /* список инициализаторов */ firstClassThread([this](){ run(); }) { }


Имей в виду что поток запустится сразу же после завершения конструктора `std::thread`.

en.cppreference.com/w/cpp/thread/thread
Threads begin execution immediately upon construction of the associated thread object (pending any OS scheduling delays), starting at the top-level function provided as a constructor argument.

Буквально, поток запускается сразу после его конструирования.

en.cppreference.com/w/cpp/thread/thread/detach
Separates the thread of execution from the thread object, allowing execution to continue independently.

А вот `detach` ничего с запуском потока, или с самим потоком, не делает, она только сбрасывает состояние объекта потока, обрывает связь между объектом потока и самим потоком.

Может тебе стоит как-то иначе запускать поток, в другое время? Если тебе все таки надо запустить поток в другое время, его в это время и надо конструировать.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы