2015-02-21 4 views
0

При составлении программы ниже, я получаю сообщение об ошибке:правильный способ создания packaged_task

Ошибка 1 Ошибка C2228: слева от «.get_future» должен иметь класс/структуры/объединения C: \ Users \ haliaga \ documents \ visual studio 2010 \ projects \ test \ test \ accumulateexceptionsafe.cpp 62 1 Тест

, который на самом деле не является реальной проблемой.

если вы комментируйте строки:

//futures[i]=task.get_future(); 
//threads[i]=std::thread(std::move(task),block_start,block_end); 
//block_start=block_end; 

вы получите ниже предупреждение, которое говорит, что "ТАСК" не называли:

* предупреждение C4930: «зЬй :: packaged_task <> task (accumulate_block (__cdecl ) (void)) ': прототипная функция не была вызвана (было ли определено определение переменной?) 1> с 1> [ 1> = int (std :: _ List_iterator >>, std :: _ List_iterator >>), 1> Iterator = std :: _ List_iterator >>, 1> T = INT 1>]

что бы правильный способ задания:

std::packaged_task<T(Iterator,Iterator)> task(accumulate_block<Iterator,T>()); 

?

Спасибо

PS: найти ниже код:

#include <list> 
#include <numeric> 
#include <vector> 
#include <thread> 
#include <future> 

using namespace std; 
template<typename Iterator,typename T> 
struct accumulate_block 
{ 
    T operator()(Iterator first, Iterator last) 
    { 
     std::thread::id id = std::this_thread::get_id(); 
     return std::accumulate(first, last, T()); 
    } 
}; 

class join_threads 
{ 
    std::vector<std::thread>& threads; 
public: 
    explicit join_threads(std::vector<std::thread>& threads_): 
    threads(threads_) 
    { 
     std::thread::id id = std::this_thread::get_id(); 
    } 
    ~join_threads() 
    { 
     std::thread::id id = std::this_thread::get_id(); 
     for(unsigned long i=0;i<threads.size();++i) 
     { 
      if(threads[i].joinable()) 
       threads[i].join(); 
     } 
    } 
}; 

template<typename Iterator,typename T> 
T parallel_accumulate(Iterator first,Iterator last,T init) 
{ 
    std::thread::id id = std::this_thread::get_id(); 
    unsigned long const length=std::distance(first,last); 
    if(!length) 
     return init; 
    unsigned long const min_per_thread=25; 
    unsigned long const max_threads=(length+min_per_thread-1)/min_per_thread; 
    unsigned long const hardware_threads=std::thread::hardware_concurrency(); 
    unsigned long const num_threads=std::min(hardware_threads!=0?hardware_threads:2,max_threads); 
    unsigned long const block_size=length/num_threads; 
    std::vector<std::future<T> > futures(num_threads-1); 
    std::vector<std::thread> threads(num_threads-1); 
    join_threads joiner(threads); 
    Iterator block_start=first; 
    for(unsigned long i=0;i<(num_threads-1);++i) 
    { 
     Iterator block_end=block_start; 
     std::advance(block_end,block_size); 
     std::packaged_task<T(Iterator,Iterator)> task(accumulate_block<Iterator,T>()); 
     futures[i]=task.get_future(); 
     threads[i]=std::thread(std::move(task),block_start,block_end); 
     block_start=block_end; 
    } 
    T last_result=accumulate_block<Iterator, T>()(block_start,last); 
    T result=init; 
    for(unsigned long i=0;i<(num_threads-1);++i) 
    { 
     result+=futures[i].get(); 
    } 
    result += last_result; 
    return result; 
}; 

int main() 
{ 
    list<int> l; 
    for(int i=0; i<26; ++i) 
     l.push_back(i); 

    std::thread::id id = std::this_thread::get_id(); 
    int res = ::parallel_accumulate(l.begin(), l.end(), 0); 

    return 0; 
} 

ответ

4

раздосадовать разобрана.

std::packaged_task<T(Iterator,Iterator)> task(accumulate_block<Iterator,T>()); 

объявляет функцию под названием task, который принимает параметр типа указатель на функцию не принимает никаких аргументов и возвращает accumulate_block<Iterator,T> и возвращает std::packaged_task<T(Iterator,Iterator)>.

неоднозначность с использованием единообразного синтаксиса инициализации:

std::packaged_task<T(Iterator,Iterator)> task(accumulate_block<Iterator,T>{}); 

Или с дополнительной парой круглых скобок для древних компиляторов, которые не имеет поддержки единой инициализации:

std::packaged_task<T(Iterator,Iterator)> task((accumulate_block<Iterator,T>())); 
//           ^       ^
+0

Спасибо за совет, но на MSVC2012 Я получаю эту ошибку: Ошибка ошибка C2143: синтаксическая ошибка: отсутствует ')' before '{' – user2286810

+0

@ user2286810 Используйте пару парсенов. См. Обновление. –

+0

Я вижу вас исправление, спасибо! – user2286810