代码之家  ›  专栏  ›  技术社区  ›  f1msch

一个唯一可移动的物体能变成一个shared_ptr吗?

  •  0
  • f1msch  · 技术社区  · 3 年前

    我正在阅读的开源代码 thread_pool

    它表明

    // add new work item to the pool
    template<class F, class... Args>
    auto ThreadPool::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::unique_lock<std::mutex> lock(queue_mutex);
    
            // don't allow enqueueing after stopping the pool
            if(stop)
                throw std::runtime_error("enqueue on stopped ThreadPool");
    
            tasks.emplace([task](){ (*task)(); });
        }
        condition.notify_one();
        return res;
    }
    

    据我所知, std::packaged_task 是唯一可移动的对象,的shared_ptr也可以 task …制的 std::packaged_task ?因为 std::packaged_task 不可能 shared .

    但以一种令人反感的方式,在判决中 tasks.emplace([task](){ (*task)(); }); , 任务 是复制到lambda中的值,所以它也意味着的shared_ptr中的计数吗 任务 将被添加到2?这意味着 std::packaged_task 实际上是 共享 分成两份。

    那么,一个唯一可移动的对象可以被做成shared_ptr吗?我的上述想法有错吗?

    1 回复  |  直到 3 年前
        1
  •  7
  •   user17732522    3 年前

    智能指针甚至不需要元素类型是可移动的。他们从不试图以任何形式复制 make_shared 做的是先构造一个对象,然后 shared_ptr 只需传递一个指向单个对象的指针。

    正在复制 shared_ptr 就像复制一个原始指针(当然还有引用计数)。它不会复制指向的对象。

    如果您手动所做的只是使用 new 创建一次,然后处理(的副本)生成的原始指针。