我在macOS中尝试了以下代码,导致编译错误。我的问题是在创建线程时将参数传递给函数的最佳方法是什么?
#include <iostream>
#include <vector>
#include <thread>
#include <utility>
#include <functional>
void merge(std::vector<int> &v, int l, int m, int r) {
int i = l;
int j = m + 1;
std::vector<int> temp;
while (i <= m && j <= r) {
if (v.at(i) <= v.at(j)) {
temp.push_back(v.at(i++));
}
else {
temp.push_back(v.at(j++));
}
}
while (i <= m) {
temp.push_back(v.at(i++));
}
while (j <= r) {
temp.push_back(v.at(j++));
}
std::copy(temp.begin(), temp.end(), v.begin() + l);
}
void mergesort(std::vector<int> &v, int l, int r) {
if (l < r) {
int m = (l + r) / 2;
std::thread sort_thread1(mergesort, std::ref(v), l, m);
std::thread sort_thread2(mergesort, std::ref(v), m + 1, r);
sort_thread1.join();
sort_thread2.join();
merge(v, l, m, r);
}
}
int main(void) {
int n;
std::vector<int> v;
std::cin >> n;
for (int i = 0; i < n; ++i) {
int a;
std::cin >> a;
v.push_back(a);
}
mergesort(v, 0, n - 1);
for (const int &a : v) {
std::cout << a << " ";
}
std::cout << std::endl;
return 0;
}
我在这里尝试过clang和g ++,但得到的错误如下:
~/Desktop> g++-6 mergesort.cpp -std=c++11 -pthread
mergesort.cpp: In function 'void mergesort(std::vector<int>&, int, int)':
mergesort.cpp:31:62: error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, std::reference_wrapper<std::vector<int> >, int&, int&)'
std::thread sort_thread1(mergesort, std::ref(v), l, m);
^
In file included from mergesort.cpp:3:0:
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:128:7: note: candidate: template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...)
thread(_Callable&& __f, _Args&&... __args)
^~~~~~
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:128:7: note: template argument deduction/substitution failed:
mergesort.cpp:31:62: note: couldn't deduce template parameter '_Callable'
std::thread sort_thread1(mergesort, std::ref(v), l, m);
^
In file included from mergesort.cpp:3:0:
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:123:5: note: candidate: std::thread::thread(std::thread&&)
thread(thread&& __t) noexcept
^~~~~~
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:123:5: note: candidate expects 1 argument, 4 provided
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:117:5: note: candidate: std::thread::thread()
thread() noexcept = default;
^~~~~~
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:117:5: note: candidate expects 0 arguments, 4 provided
mergesort.cpp:32:66: error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, std::reference_wrapper<std::vector<int> >, int, int&)'
std::thread sort_thread2(mergesort, std::ref(v), m + 1, r);
^
In file included from mergesort.cpp:3:0:
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:128:7: note: candidate: template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...)
thread(_Callable&& __f, _Args&&... __args)
^~~~~~
答案 0 :(得分:0)
将第31/32行更改为:
std::thread sort_thread1([&v, l, m] { mergesort(v, l, m); });
std::thread sort_thread2([&v, m, r] { mergesort(v, m + 1, r); });
会让它编译。</ p>
我不认为这是正确的:
输入:
5 4 3 2 1 0
输出
0 1 2 3 4
答案 1 :(得分:0)
编译器说它couldn't deduce template parameter '_Callable'
,所以我们明确指定了重载版本。
以下更改
// ...
typedef void (*mergesort_ptr_t)(std::vector<int> &v, int l, int r);
void mergesort(std::vector<int> &v, int l, int r) {
if (l < r) {
int m = (l + r) / 2;
std::thread sort_thread1((mergesort_ptr_t)(mergesort), std::ref(v), l, m);
std::thread sort_thread2((mergesort_ptr_t)(mergesort), std::ref(v), m + 1, r);
// ...
似乎有效。
编译器信息:
➜ Downloads g++ -std=c++11 sxkdzmtsort.cpp
➜ Downloads g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/c++/4.2.1
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin