将使用 packaged_task 的 lambda 任务放入队列中

问题描述 投票:0回答:0

所以我有一个线程池的入队实现

     template <typename F, typename... Args>
        auto enqueue(F&& f, Args&&... args) -> std::future<decltype(f(args...))> {
            using return_type = decltype(f(args...));
            auto task = std::make_shared<std::packaged_task<return_type()>>(
                    std::bind(std::forward<F>(f), std::forward<Args>(args)...)
            );
            auto result = task->get_future();
            {
                std::unique_lock<std::mutex> lock(m_queue_mutex);
                if (m_stop)
                    throw std::runtime_error("enqueue on stopped ThreadPool");
                m_tasks.emplace([task]() { (*task)(); });
            }
            m_condition.notify_one();
            return result;
        }

到目前为止一切顺利,但我想避免使用内存分配而不使用 make_shared。

所以我改成这样:

template <typename F, typename... Args>
    auto enqueue(F&& f, Args&&... args) -> std::future<decltype(f(args...))> {
        using return_type = decltype(f(args...));
        auto task = std::packaged_task<return_type()>(
                std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );
        auto result = task.get_future();
        {
            std::unique_lock<std::mutex> lock(m_queue_mutex);
            if (m_stop)
                throw std::runtime_error("enqueue on stopped ThreadPool");
            m_tasks.emplace([task = std::move(task)]() mutable { task(); });
        }
        m_condition.notify_one();
        return result;
    }

据我所知,这里没有copy。 任务应该移到 lambda 中,lambda 应该移到队列中,但我仍然收到此错误

使用删除函数‘std::packaged_task<_Res(_ArgTypes ...)>::packaged_task(const std::packaged_task<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]' 38 | m_tasks.emplace(任务可变{任务();});

我的理解是我正在尝试复制 packaged_task 并且它的复制构造函数被删除了。

在这里你可以玩完整的代码

https://godbolt.org/z/bEsPfabz6

谢谢!

c++ copy-constructor
© www.soinside.com 2019 - 2024. All rights reserved.