线程不适用于带有模板参数的函数

时间:2015-08-19 16:21:42

标签: c++ multithreading c++11

我正在尝试实现多线程合并排序,但我的尝试无法编译。这是我的代码:

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;

1 个答案:

答案 0 :(得分: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);});