packaged_task пример проблемы? Модификация примера Страуструпа - PullRequest
0 голосов
/ 28 мая 2020

Я пытаюсь изменить пример, приведенный в Stroustrup C ++, 4-е издание, стр. 122, чтобы вызвать функцию аккумулятора () напрямую с итераторами. В частности, удалите использование * double и используйте итераторы.

Пока что у меня есть это, однако у него есть проблемы с компиляцией, которых я не понимаю.

Есть ли у кого-нибудь указатели на выполнение этого?

#include <iostream>
#include <memory>
#include <thread>
#include <numeric>
#include <vector>
#include <future>
using namespace std;

double comp2(vector<double>& v) {
  using Task_type = double(vector<double>::iterator,
               vector<double>::iterator, double);

  packaged_task<Task_type> pt0 {accumulate};
  packaged_task<Task_type> pt1 {accumulate};

#if 0
  future<double> f0 {pt0.get_future()};
  future<double> f1 {pt1.get_future()};

  double *first = &v[0];
  // move required bc package_task cannot be copied
  thread t1 {move(pt0), first, first + v.size()/2, 0};
  thread t2 {move(pt1), first + v.size()/2, first + v.size(), 0};

  t1.join();
  t2.join();

  return f0.get() + f1.get();
#endif
}

int main(int argc, char *argv[])
{
  vector<double> v = {1.0, 1.0, 1.0, 1.0};

  cout << "v: " << comp2(v) << endl;

  return 0;
}

и ошибка:

g++ -lpthread -pedantic -Wall test87.cc && ./a.out
test87.cc: In function ‘double comp2(std::vector<double>&)’:
test87.cc:13:43: error: no matching function for call to ‘std::packaged_task<double(__gnu_cxx::__normal_iterator<double*, std::vector<double> >, __gnu_cxx::__normal_iterator<double*, std::vector<double> >, double)>::packaged_task(<brace-enclosed initializer list>)’
   packaged_task<Task_type> pt0 {accumulate};
                                           ^
In file included from test87.cc:6:
/usr/include/c++/8/future:1528:2: note: candidate: ‘template<class _Allocator> std::packaged_task<_Res(_ArgTypes ...)>::packaged_task(std::allocator_arg_t, const _Allocator&, std::packaged_task<_Res(_ArgTypes ...)>&&)’
  packaged_task(allocator_arg_t, const _Allocator&,
  ^~~~~~~~~~~~~
/usr/include/c++/8/future:1528:2: note:   template argument deduction/substitution failed:
test87.cc:13:43: note:   candidate expects 3 arguments, 1 provided
   packaged_task<Task_type> pt0 {accumulate};

1 Ответ

1 голос
/ 29 мая 2020

std::accumulate - это не функция, это шаблон функции. Чтобы построить packaged_task, вам необходимо передать ему конкретную функцию, например:

packaged_task<Task_type> pt0 {accumulate<vector<double>::iterator, double>};
packaged_task<Task_type> pt1 {accumulate<vector<double>::iterator, double>};

Вы также должны сделать first итератором вместо указателя, поскольку это не гарантирует, что итератор будет реализован как указатель.

auto first = v.begin();

Вот демонстрация .

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