You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用auto与std::vector构建递归结构时对象过早销毁问题

树形结构子节点过早销毁无法显示的原因及解决

我在实现树形结构时编写了如下代码:

#include <iostream>
#include <string>
#include <string_view>
#include <vector>

struct Node
{
    std::string _name;
    std::vector<Node> _subnodes;

    Node(const std::string_view sv) : _name(sv), _subnodes() {
        //std::cout << "construct '" << _name << "'" << std::endl;
    }
    ~Node() {
        //std::cout << "destruct '" << _name << "'" << std::endl;
    }

    Node& add(const std::string_view sv) {
        return _subnodes.emplace_back(sv);
    }

    void dump(size_t indent=0) const {
        for (size_t i=0; i<indent; i++) {
            std::cout << "  ";
        }
        std::cout << _name << std::endl;

        for (const auto& n : _subnodes) {
            n.dump(indent+1);
        }
    }
};

int main()
{
    auto root = Node("root");
    
    auto alpha = root.add("alpha");
    alpha.add("one");
    alpha.add("two");
    alpha.add("three");

    auto beta  = root.add("beta");
    beta.add("four");
    beta.add("five");
    beta.add("six");

    auto gamma = root.add("gamma");
    gamma.add("seven");
    gamma.add("eight");
    gamma.add("nine");

    root.dump();

    return 0;
}

不知为何,子节点“one”至“nine”过早销毁,无法在dump输出中显示。该现象似乎不依赖于所使用的编译器,请问这是什么原因?


问题原因

核心问题出在变量声明时未使用引用:

add函数返回的是Node&(容器中新添加节点的引用),但你用auto alpha = root.add("alpha");声明变量时,auto会推导为Node而非Node&,这会触发拷贝构造,生成一个alpha的局部副本。后续调用alpha.add("one")等操作,都是在这个副本上添加子节点,而非修改root容器中实际存储的alpha节点。

当这个局部副本的生命周期结束(比如执行到下一行声明beta时),它会被销毁,其包含的子节点(one、two、three)也会随之销毁。而root里的alpha节点自始至终都没有子节点,所以dump时自然看不到这些子节点。

解决方法

将alpha、beta、gamma的声明改为引用类型,在auto后添加&:

auto& alpha = root.add("alpha");
auto& beta  = root.add("beta");
auto& gamma = root.add("gamma");

这样变量会直接绑定到root容器内的节点上,后续添加子节点的操作都会作用于真实存储的节点,不会产生临时副本,子节点也就不会被提前销毁,dump时就能正常显示所有层级的节点了。


内容的提问来源于stack exchange,提问作者md2perpe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 13:43:09