2015-08-19 26 views
2

我想實現多線程合併排序,但是我的嘗試無法編譯。這裏是我的代碼:線程不能用於具有模板參數的函數

template <class RandomAccessIterator> 
void merge_sort (RandomAccessIterator begin,RandomAccessIterator end) 
{ 
    int N = end - begin; 
    int N1,N2; 

    if (N == 1) 
     return; 

    RandomAccessIterator mid = begin + (end-begin)/2; 


    // merge_sort (begin,mid); // this is OK 
    // merge_sort (mid,end); // this is OK 

    thread t1 (merge_sort,begin,mid); // error 
    thread t2 (merge_sort,mid,end); // error 

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

    N1 = mid - begin; 
    N2 = end - mid; 

    merge (begin,N1,mid,N2); 
} 

錯誤從GCC消息(g++ -std=c++11 merge-multithread.cpp):

merge-multithread.cpp: In instantiation of ‘void merge_sort(RandomAccessIterator, RandomAccessIterator) [with RandomAccessIterator = int*]’: 
merge-multithread.cpp:76:25: required from here 
merge-multithread.cpp:60:33: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, int*&, int*&)’ 
    thread t1 (merge_sort,begin,mid); 
           ^
In file included from merge-multithread.cpp:4:0: 
/usr/include/c++/5.2.0/thread:133:7: note: candidate: template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...) 
     thread(_Callable&& __f, _Args&&... __args) 
    ^
/usr/include/c++/5.2.0/thread:133:7: note: template argument deduction/substitution failed: 
merge-multithread.cpp:60:33: note: couldn't deduce template parameter ‘_Callable’ 
    thread t1 (merge_sort,begin,mid); 
           ^
In file included from merge-multithread.cpp:4:0: 
/usr/include/c++/5.2.0/thread:128:5: note: candidate: std::thread::thread(std::thread&&) 
    thread(thread&& __t) noexcept 
    ^
/usr/include/c++/5.2.0/thread:128:5: note: candidate expects 1 argument, 3 provided 
/usr/include/c++/5.2.0/thread:122:5: note: candidate: std::thread::thread() 
    thread() noexcept = default; 
+0

我很好奇你的性能在這方面是如何提高的。首先,當列表中少於幾個元素作爲特殊情況時,處理它可能會更好(排序說... ... 4個冒泡排序的元素可能比創建另外2個線程的開銷要快3個調用合併)。但它也很好奇,因爲當你需要合併越來越大的數組時,你會用更少的線程來完成它。 (例如,最後一次合併,最大的將是單線程)。 – RyanP

+1

編譯錯誤的關鍵部分是「'<無法解析的重載函數類型>'」。良好的模式來承諾記憶。 – Barry

回答

6

merge_sort本身就是一個函數模板;要了解你需要指定所有的模板參數實例化的功能之一的地址:

thread t1 (&merge_sort<RandomAccessIterator>,begin,mid); 
//   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ 

或使用靜態澆鑄:

thread t1 (static_cast<void(*)(RandomAccessIterator,RandomAccessIterator)>(&merge_sort),begin,mid); 

...或使用lambda表達式,讓編譯器自動推斷出參數的類型:

thread t1 ([begin,mid]{merge_sort(begin, mid);}); 
+0

我自己點了231個。 – Yakk

相關問題