Как передать элементы структуры асинхронным потокам? - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь запустить функцию с использованием launch::async.Однако я заметил, что это не работает при передаче элементов структуры в качестве параметра:
Код

#include <future>
#include <vector>
#include <thread>

struct example { int ten; };

void threadFunction(int number, std::string hi) { 
   printf("%s Your number is %d\n", hi.c_str(), number + 1);
}

int main() {
   example ex;
   ex.ten = 9;
   std::string someString = "Hi there!";
   std::vector< std::future< void > > threads(5);
   for (uint16_t s = 0; s < 5; s += 1) {
      threads[s] = async(std::launch::async,
                                   [ex.ten,
                                   someString] {
         threadFunction(ex.ten, someString);
      });
   }
}

выдает следующие ошибки:

file.cpp: In function ‘int main()’:
file.cpp:25:39: error: expected ‘,’ before ‘.’ token
                                    [ex.ten,
                                       ^
file.cpp:25:39: error: expected identifier before ‘.’ token
file.cpp:25:43: error: expected ‘]’ before ‘,’ token
                                    [ex.ten,
                                           ^
file.cpp: In lambda function:
file.cpp:25:43: error: expected ‘{’ before ‘,’ token
file.cpp: In function ‘int main()’:
file.cpp:26:46: error: expected ‘)’ before ‘]’ token
                                    someString] {
                                              ^
file.cpp:28:8: error: expected primary-expression before ‘)’ token
       });

При замене ex.tenс другой переменной ten это работает.

Итак, мои вопросы:
1. Почему launch :: async не работает со элементами структуры?
2. Есть ли способ сделать это более элегантным способом, чем создать переменнуюдля каждого элемента в структуре и передать эти переменные вместо?(например, int ten = ex.ten; и т. д.)

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Вы не можете передать одно структурное поле таким образом в лямбду в C ++.Полученная ошибка не связана с std::launch или не связана между потоками.Вместо этого вы можете сделать следующее:

C ++ 11 - скопировать поле в локальную переменную и записать эту переменную:

auto ten = ex.ten;
threads[s] = async(std::launch::async,
                               [ten,
                               someString] {
     threadFunction(ten, someString);})

C ++ 14 и более поздние версии - инициализировать переменную в списке захвата:

threads[s] = async(std::launch::async,
                               [ten = ex.ten,
                               someString] {threadFunction(ten, someString);})
0 голосов
/ 23 января 2019

То, что вы пытаетесь сделать, это захватить поле в структуре в лямбде. Это невозможно, вы можете захватить только всю структуру.

Это не имеет ничего общего с std::launch, это базовое свойство лямбда-замыкания.

В C ++ 14 вы можете иметь захваты с инициализаторами, что может быть тем, что вы хотите:

 auto lam = [ten = ex.ten]...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...