request for member ‘get_future’ in ‘task’, which is of non-class type ‘std::packaged_task<int(__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> >)>(accumulate_block<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, int> (*)())’ futures[i]=task.get_future();
时间: 2024-03-15 21:44:02 浏览: 124
这个错误的原因是`task`变量的类型不是一个类类型,因此不能调用`get_future()`函数。在这里,`task`的类型是一个函数类型,它返回一个`std::packaged_task`对象,而不是一个`std::packaged_task`对象本身。
要解决这个错误,需要在创建`std::packaged_task`对象时使用函数类型的别名或函数指针类型。例如,如果要使用函数类型别名`Func`来定义`std::packaged_task`对象,可以这样写:
```c++
using Func = int(std::vector<int>::iterator, std::vector<int>::iterator);
std::packaged_task<Func> task(accumulate_block<int>);
```
或者,使用函数指针类型`FuncPtr`定义`std::packaged_task`对象,可以这样写:
```c++
using FuncPtr = int(*)(std::vector<int>::iterator, std::vector<int>::iterator);
std::packaged_task<FuncPtr> task(&accumulate_block<int>);
```
这样可以确保`task`的类型为`std::packaged_task`,从而可以调用`get_future()`函数获取与任务关联的`std::future`对象。
相关问题
#include <vector> #include <queue> #include <thread> #include <mutex> #include <condition_variable> #include <functional> #include <future> class ThreadPool { public: ThreadPool(size_t threads) : stop(false) { for (size_t i = 0; i < threads; ++i) { workers.emplace_back([this] { for (;;) { std::function<void()> task; { std::unique_lock<std::mutex> lock(this->queue_mutex); this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); }); if (this->stop && this->tasks.empty()) return; task = std::move(this->tasks.front()); this->tasks.pop(); } task(); } }); } } ~ThreadPool() { { std::unique_lock<std::mutex> lock(queue_mutex); stop = true; } condition.notify_all(); for (std::thread &worker : workers) worker.join(); } template<class F, class... Args> auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> { using return_type = typename std::result_of<F(Args...)>::type; auto task = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...)); std::future<return_type> res = task->get_future(); { std_lock<std::mutex> lock(queue_mutex); if (stop) throw std::runtime_error("enqueue on stopped ThreadPool"); tasks.emplace([task] { (*task)(); }); } condition.notify_one(); return res; } private: std::vector<std::thread> workers; std::queue<std::function<void()>> tasks; std::mutex queue_mutex; std::condition_variable condition; bool stop; };
这是一个 C++ 实现的线程池类。它可以在创建时指定线程数,然后通过 `enqueue` 方法将任务提交到线程池中执行。线程池会自动创建多个线程来执行任务,并且可以动态调整线程池大小,以适应任务负载的变化。这个实现使用了 C++11 中的标准库,包括 `std::thread`、`std::mutex`、`std::condition_variable` 等。它还提供了一个 `std::future` 对象,可以用来获取任务执行的结果。
template<class T, class ...Args> auto ThreadPool::InsertQueue(T&& t, Args&& ...args)->future<decltype(t(args...))> { using Type = decltype(t(args...)); auto task = make_shared<packaged_task<Type()>>(bind(forward<T>(t), forward<Args>(args)...)); future<Type> res = task->get_future(); { unique_lock<mutex> lock(mtx_queue); if (stop) { throw runtime_error("停止。。"); } task.emplace([task] { (*task)(); }); } cv.notify_one(); return res; }报错严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C2039 "emplace": 不是 "std::shared_ptr<std::packaged_task<Type (void)>>" 的成员 C++More F:\LH_Work\C++Work\C++More\C++More\main.cpp 103
这个错误是因为在这段代码中,`task` 是一个 `shared_ptr` 对象,而 `shared_ptr` 类型没有名为 `emplace` 的成员函数。
解决这个错误的方法是将 `task` 的类型更正为 `std::packaged_task<Type()>`,而不是 `std::shared_ptr<std::packaged_task<Type()>>`。然后在 lambda 表达式中直接使用 `task()` 调用任务函数。
以下是修改后的代码:
```cpp
template<class T, class ...Args>
auto ThreadPool::InsertQueue(T&& t, Args&& ...args) -> future<decltype(t(args...))>
{
using Type = decltype(t(args...));
auto task = make_shared<packaged_task<Type()>>(bind(forward<T>(t), forward<Args>(args)...));
future<Type> res = task->get_future();
{
unique_lock<mutex> lock(mtx_queue);
if (stop)
{
throw runtime_error("停止。。");
}
tasks.emplace([task]
{
(*task)();
});
}
cv.notify_one();
return res;
}
```
请注意,我还修改了 `task.emplace` 为 `tasks.emplace`,因为任务队列应该是 `tasks` 而不是 `task`。
阅读全文