首页 > 解决方案 > 隐式复制的构造函数智能指针

问题描述

我有以下代码:

#include <vector>
#include <memory>

struct Node{
    int value;
    Node *left = nullptr;
    Node *right = nullptr;
};

std::vector<std::unique_ptr<Node>> createListNodes(int min, int max)
{
    // odered vector with i.e. {0,1,2,3,4}
    std::vector<std::unique_ptr<Node>> alternative;
    if (min == max)
    {
        alternative.emplace_back(std::make_unique<Node>(min,nullptr,nullptr)); // it is a leaf node
        return  alternative;
    }
    for (int i=min; i<=max; i++)
    {
        std::vector<std::unique_ptr<Node>> left = createListNodes(min,i-1); // for the left side
        std::vector<std::unique_ptr<Node>> right = createListNodes(i+1,max); // for the left side
        if (left.size() == 0) // if node i has just one child and it is in the right
        {
            for (auto elem_right : right) // ERROR
            {
                alternative.emplace_back(std::make_unique<Node>(i,nullptr,elem_right));
            }
        }
        else if (right.size() == 0) // if node i has just one child and it is in the left
        {
            for (auto elem_left : left) // ERROR
            {   
                alternative.emplace_back(std::make_unique<Node>(i,elem_left,nullptr));
            }
        }
        for (auto elem_left : left) // ERROR
        {
            for (auto elem_right : right) // ERROR
            {
                alternative.emplace_back(std::make_unique<Node>(i,elem_left,elem_right));
            }
        }
    }
    return alternative;

}

int main()
{
    int N = 4;
    std::vector<std::unique_ptr<Node>> combinations = createListNodes(0, N);
}

迭代 unique_ptr 的向量时收到错误消息,但我无法理解真正的问题。我也尝试将 unique_ptr 移动到向量替代项,但问题仍然存在。

error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<Node,
      std::__1::default_delete<Node> >'
            for (auto elem_left : left)

标签: c++smart-pointers

解决方案


您可能会执行以下操作:

你有几个问题,你迭代副本,而不是参考。

内部节点的生命周期在每次循环迭代时停止。

你可以让节点拥有它的孩子:

struct Node{
    int value;
    std::unique_ptr<Node> left = nullptr;
    std::unique_ptr<Node> right = nullptr;

    Node(int v, std::unique_ptr<Node> left = nullptr, std::unique_ptr<Node>right = nullptr) :
        value(v), left(std::move(left)), right(std::move(right))
    {}

    std::unique_ptr<Node> DeepCopy() const
    {
        return std::make_unique<Node>(value,
            left ? left->DeepCopy() : nullptr,
            right ? right->DeepCopy() : nullptr);
    }
};

std::vector<std::unique_ptr<Node>> createListNodes(int min, int max)
{
    // odered vector with i.e. {0,1,2,3,4}
    std::vector<std::unique_ptr<Node>> alternative;
    if (min == max)
    {
        alternative.emplace_back(std::make_unique<Node>(min, nullptr, nullptr)); // it is a leaf node
        return  alternative;
    }
    for (int i=min; i<=max; i++)
    {
        std::vector<std::unique_ptr<Node>> left = createListNodes(min, i-1); // for the left side
        std::vector<std::unique_ptr<Node>> right = createListNodes(i+1, max); // for the left side
        if (left.size() == 0) // if node i has just one child and it is in the right
        {
            for (auto& elem_right : right)
            {
                alternative.emplace_back(std::make_unique<Node>(i, nullptr, std::move(elem_right)));
            }
        }
        else if (right.size() == 0) // if node i has just one child and it is in the left
        {
            for (auto& elem_left : left)
            {   
                alternative.emplace_back(std::make_unique<Node>(i, std::move(elem_left), nullptr));
            }
        }
        for (auto& elem_left : left)
        {
            for (auto& elem_right : right)
            {
                alternative.emplace_back(std::make_unique<Node>(i, elem_left->DeepCopy(), elem_right->DeepCopy()));
            }
        }
    }
    return alternative;
}

演示(带std::unique_ptr

演示(带std::shared_ptr


推荐阅读