2014-02-27 71 views
1

我對C++和編程一般都很陌生。爲了練習,我製作了一個類似於mergesort的排序算法。然後我試着讓它成爲多線程的。當使用std :: async時,C++「無法推導出模板參數」

std::future<T*> first = std::async(std::launch::async, &mergesort, temp1, temp1size); 
    std::future<T*> second = std::async(std::launch::async, &mergesort, temp2, temp2size); 
    temp1 = first.get(); 
    temp2 = second.get(); 

但似乎我的編譯器無法決定使用哪個模板,因爲我得到相同的錯誤兩次。

Error 1 error C2783: 'std::future<result_of<enable_if<std::_Is_launch_type<_Fty>::value,_Fty>::type(_ArgTypes...)>::type> std::async(_Policy_type,_Fty &&,_ArgTypes &&...)' : could not deduce template argument for '_Fty' 
Error 2 error C2784: 'std::future<result_of<enable_if<!std::_Is_launch_type<decay<_Ty>::type>::value,_Fty>::type(_ArgTypes...)>::type> std::async(_Fty &&,_ArgTypes &&...)' : could not deduce template argument for '_Fty &&' from 'std::launch' 

的錯誤導致我相信的std ::異步超載有兩個不同的模板,一個指定策略和一個未指定,編譯器無法選擇正確的(我使用Visual Studio Express 2013)。那麼如何向編譯器指定適當的模板呢? (做std::future<T*> second = std::async<std::launch::async>(&mergesort, temp2, temp2size);似乎不工作,我得到無效的模板參數,預期類型)。還有更好的方法來完成這一切嗎? 謝謝!

+0

'mergesort'重載?如果是這樣的話,'&mergesort'在這種情況下是不明確的。 – Simple

+0

不,mergesort的唯一定義是'template T * mergesort(T * arg,int size)' – Antrikos

+0

好吧,它仍然與模板不一致,因爲模板基本上會標記大量重載。 – Simple

回答

0

您需要指定mergesort的模板參數。異步並不會足夠聰明,無法自行解決問題。下面是一個基於迭代器的示例。它還利用當前活動線程作爲遞歸點,而不是刻錄等待兩個其他線程的線程句柄。

我提醒你,有更好的方法來做到這一點,但調整這可能足以滿足你的需求。

#include <iostream> 
#include <algorithm> 
#include <vector> 
#include <thread> 
#include <future> 
#include <random> 
#include <atomic> 

static std::atomic_uint_fast64_t n_threads = ATOMIC_VAR_INIT(0); 

template<typename Iter> 
void mergesort(Iter begin, Iter end) 
{ 
    auto len = std::distance(begin,end); 

    if (len <= 16*1024) // 16K segments defer to std::sort 
    { 
     std::sort(begin,end); 
     return; 
    } 

    Iter mid = std::next(begin,len/2); 

    // start lower parttion async 
    auto ft = std::async(std::launch::async, mergesort<Iter>, begin, mid); 
    ++n_threads; 

    // use this thread for the high-parition. 
    mergesort(mid, end); 

    // wait on results, then merge in-place 
    ft.wait(); 
    std::inplace_merge(begin, mid, end); 
} 

int main() 
{ 
    std::random_device rd; 
    std::mt19937 rng(rd()); 
    std::uniform_int_distribution<> dist(1,100); 

    std::vector<int> data; 
    data.reserve(1024*1024*16); 
    std::generate_n(std::back_inserter(data), data.capacity(), 
        [&](){ return dist(rng); }); 

    mergesort(data.begin(), data.end()); 
    std::cout << "threads: " << n_threads << '\n'; 
} 

輸出

threads: 1023 

你得相信我,到底矢量進行排序。不會將16MB的值轉儲到此答案中。

注意:這是在Mac上使用clang 3.3編譯和測試的,運行沒有問題。我的gcc 4.7.2不幸的是腦死亡,因爲它拋出了共享計數中止的cookie,但我對它所在的libstdC++或VM沒有高度的信心。