【问题标题】:How to feed a shared_ptr to a template function that shall add various data types to a vector?如何将 shared_ptr 提供给应将各种数据类型添加到向量的模板函数?
【发布时间】:2021-02-26 10:26:23
【问题描述】:

this question 中,建议使用std::shared_ptr 而不是std::unique_ptr。但是,当将此共享指针提供给我的函数时,我无法完成这项工作:

 std::vector<std::unique_ptr<segment>> v3;

    //VERSION 5:
    auto myLine2 = std::make_shared<Line>(start, end);
    add_segment(v3, myLine2);

这是函数的新实现:

template<typename T1, typename T2>
inline void add_segment(T1 & v, T2& line_or_circle)
{
    v.emplace_back(std::move(line_or_circle));
}

我在这里做错了什么?

【问题讨论】:

    标签: c++ shared-ptr


    【解决方案1】:

    您不能将shared_ptr 中的内容“移动”到unique_ptr 的实例中。如果可以的话,由于两个不同的智能指针在释放时试图删除其中的内容,就会出现各种问题。

    相反,只需将您的向量定义为:

    std::vector<std::shared_ptr<segment>> v3;
    

    然后,你真的不需要移动语义:

    template<typename T1, typename T2>
    inline void add_segment(T1 & v, T2& line_or_circle)
    {
        v.emplace_back(line_or_circle);
    }
    

    【讨论】:

    • 谢谢@selbie。这行得通。有时我很盲目地看到几乎显而易见的 :D 答案投票赞成。
    【解决方案2】:

    我不确定您是否愿意分享 Line 的所有权。但我希望您希望拥有一个包含唯一指针的向量。因此,当您的向量被销毁时,它会清理所有内容。如果您的向量,再次,如果您的向量负责行的生命周期。检查这个:

    template <typename T1, typename T2>
    inline void add_segment(T1 &v, std::unique_ptr<T2> line_or_circle)
    {
        v.emplace_back(std::move(line_or_circle));
    }
    
    struct Line
    {
        Line(int s, int e)
        {
            start = s;
            end = e;
        }
        int start;
        int end;
    };
    
    int main()
    {
        std::vector<std::unique_ptr<Line>> v3;
    
        auto myLine2 = std::make_unique<Line>(1, 5);
        add_segment(v3, std::move(myLine2));
    }
    

    【讨论】:

    • 这就是 OP 在原始(链接)问题中的内容,其中建议使用 shared_ptr
    • 谢谢 Oussama Ben Ghorbel。 @t.niese 是正确的。我在之前的实现中有这个,但是由于这些对象的唯一性,它不允许向我的向量添加两次相同的对象。 std::shared_ptr 终于允许向我的向量提供两次相同的对象。我仍然更喜欢一个唯一的向量,但看起来向量必须具有与其数据相同的内存管理(如果我考虑一下,这似乎是合乎逻辑的)。
    【解决方案3】:

    您至少可以发布一条错误消息吗? 或者生成足够多的代码,以便轻松重现。

    据我所知,我不相信您正确使用了std::vector::emplace_backemplace_back 将参数转发给std::unique_ptr&lt;segment&gt; 类型的构造函数。但是line 类型与std::unique_ptr&lt;segment&gt; 类型不匹配。

    【讨论】:

    • 感谢您的回答。 line 是从虚拟类段派生的类。当我遵循上述答案的建议时,它可以正常工作。
    猜你喜欢
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    相关资源
    最近更新 更多