<function-style-cast> 错误:无法从'initializer list'转换为'std::thread'
<function-style-cast> error: Cannot convert from 'initializer list' to 'std::thread'
我正在尝试使用std::threads
并行化快速排序,但我收到了一个错误,因为我刚开始多线程处理,所以我不熟悉这个错误。这个错误可能很简单,我一直在跳过它。有人能解释一下这个问题吗。这是代码和唯一出现的错误:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream> //cout, endl
#include <cstdlib> //srand
#include <algorithm>//copy, random_shuffle
#include <iterator> //ostream_iterator
#include "ratio.h"
#include <vector>
#include <iostream>
#include <thread>
#include "quicksort.h"
#include "sort_small_arrays.h"
template< typename T>
unsigned partition(T* a, unsigned begin, unsigned end) {
unsigned i = begin, last = end - 1;
T pivot = a[last];
for (unsigned j = begin; j<last; ++j) {
if (a[j]<pivot) {
std::swap(a[j], a[i]);
++i;
}
}
std::swap(a[i], a[last]);
return i;
}
/* iterative */
#define STACK
#define xVECTOR
#define xPRIORITY_QUEUE
#include <utility> // std::pair
template <typename T>
using triple = typename std::pair< T*, std::pair<unsigned, unsigned>>;
template< typename T>
struct compare_triples {
bool operator() (triple<T> const& op1, triple<T> const& op2) const {
return op1.second.first > op2.second.first;
}
};
#ifdef STACK
#include <stack>
template< typename T>
using Container = std::stack< triple<T>>;
#define PUSH push
#define TOP top
#define POP pop
#endif
#ifdef VECTOR
#include <vector>
template< typename T>
using Container = std::vector< triple<T>>;
#define PUSH push_back
#define TOP back
#define POP pop_back
#endif
#ifdef PRIORITY_QUEUE
#include <queue>
template< typename T>
using Container = std::priority_queue< triple<T>, std::vector<triple<T>>, compare_triples<T> >;
#define PUSH push
#define TOP top
#define POP pop
#endif
//Thread quicksorts a single range of elements and decrements thread counter at the end
template< typename T>
void threadsort_iterative_aux(Container<T> & ranges, int ¤tThreads)
{
triple<T> r = ranges.TOP();
ranges.POP();
T* a = r.first;
unsigned b = r.second.first;
unsigned e = r.second.second;
//base case
if (e - b<6) {
switch (e - b) {
case 5: quicksort_base_5(a + b); break;
case 4: quicksort_base_4(a + b); break;
case 3: quicksort_base_3(a + b); break;
case 2: quicksort_base_2(a + b); break;
}
continue;
}
unsigned q = partition(a, b, e);
ranges.PUSH(std::make_pair(a, std::make_pair(b, q)));
ranges.PUSH(std::make_pair(a, std::make_pair(q + 1, e)));
--currentThreads;
}
template< typename T>
void quicksort(T* a, unsigned begin, unsigned end, int num_threads)
{
//Number of threads currently running other than the main thread
int currentThreads = 0;
//Ranges of elements to sort
Container<T> ranges;
ranges.PUSH(std::make_pair(a, std::make_pair(begin, end)));
//Dynamic vector of threads
std::vector<std::thread> threads;
//Loops till all threads are done AND nothing left to sort
while (!ranges.empty() || currentThreads != 0)
{
//Doesn't bother doing anything if the range is empty but other threads are still running
if (!ranges.empty())
{
//If we can make more threads, make a thread and give it the top range to sort
if (currentThreads < num_threads)
{
++currentThreads;
threads.push_back(std::thread(threadsort_iterative_aux, std::ref(ranges), std::ref(currentThreads)));
}
//Starts sorting itself if maximum number of threads are running
else
{
triple<T> r = ranges.TOP();
ranges.POP();
T* a = r.first;
unsigned b = r.second.first;
unsigned e = r.second.second;
//Optimized sorting of a range between 2 and 5 elements
if (e - b < 6) {
switch (e - b) {
case 5: quicksort_base_5(a + b); break;
case 4: quicksort_base_4(a + b); break;
case 3: quicksort_base_3(a + b); break;
case 2: quicksort_base_2(a + b); break;
}
continue;
}
unsigned q = partition(a, b, e);
ranges.PUSH(std::make_pair(a, std::make_pair(b, q)));
ranges.PUSH(std::make_pair(a, std::make_pair(q + 1, e)));
}
}
}
}
template< typename T>
bool check_is_sorted(T* a, unsigned size)
{
for (unsigned int i = 1; i<size; ++i) {
if (!(a[i - 1] <= a[i])) {
return false;
}
}
return true;
}
bool test_int(unsigned size, unsigned num_threads) {
int* a = new int[size];
for (unsigned i = 0; i<size; ++i) { a[i] = i; }
std::srand(static_cast<unsigned int>(std::time(NULL)));
std::random_shuffle(a, a + size);
quicksort(a, 0, size, num_threads);
bool retval = check_is_sorted(a, size);
delete[] a;
return retval;
}
void test0() {
if (test_int(200, 1)) { std::cout << "OKn"; }
else { std::cout << "Failedn"; }
}
#include <cstdio> /* sscanf */
int main(int argc, char ** argv)
{
test0();
return 0;
}
严重性代码描述项目文件行错误C2440":无法从"初始值设定项列表"转换为"std::thread"第145行(包含:
threads.push_back(std::thread(threadssort_iterateve_aux,std::ref(range),std::ref(currentThreads));)
创建线程时,将triple<T>
作为第一个参数传递给threadsort_iterative_aux
,但函数需要Container<T> &
。
还要注意,通过带有此签名的非常数引用传递参数,需要在调用方一侧将参数封装在std::ref()
中。
这与std::bind
的行为基本相同:如果省略std::ref
,编译器会将值复制到绑定中,然后在调用时将该副本作为参数传递到函数调用中。但是,由于副本是不可变的,因此它将与非常量引用断开。这是一件好事,因为它可以保护您不意外失去该参数的副作用。
最后但同样重要的是,绑定机制打破了模板参数推导。由于在创建线程时并没有实际调用函数,因此编译器无法自动从参数中推导出函数的模板参数。你必须明确给出参数:
threads.push_back(std::thread(threadsort_iterative_aux<T>, std::ref(ranges), std::ref(currentThreads)));
// note the <T> here ---^
由于这些都是需要担心的一大堆绑定问题,您可能只想使用lambda,它不会出现任何问题:
threads.push_back(std::thread([&]() { threadsort_iterative_aux(ranges, currentThreads); }));
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- C++中带有List类的迭代器Segfault
- 使用"std::unordereded_map"映射到"std::list"对象
- GCC对可能有效的代码抛出init list生存期警告
- 使用std::list创建循环链表
- C2664 无法从'initializer list'转换参数
- 使用 std::min "no matching function for call to ‘min(<brace-enclosed initializer list>)’"时出错
- 在C++中标记化"Braced Initializer List"样式字符串(使用 Boost?
- "默认参数":无法从'initializer list'转换为'std::initializer_list'
- 无法从'initializer-list'转换为用户控制器
- 如何修复<function-style-cast>错误:无法从'initializer list'转换为asdending比较<W>(模板函子)
- 递归调用中出现错误"[Error] expression list treated as compound expression in initializer [-fpermissive]"
- VS2015无法从'initializer list'转换为'std::string'错误
- 编译器错误:"Non-aggregates cannot be initialized with initializer list."
- 无法转换...从 '<brace-enclosed initializer list>' 到 地图
- 无法将'<brace-enclosed initializer list>'转换为'double'作为回报
- <function-style-cast> 错误:无法从'initializer list'转换为'std::thread'
- initializer语言 - list不能转换为const margin *