【问题标题】:Why vector children is not modified?为什么vector children没有被修改?
【发布时间】:2020-02-03 14:45:36
【问题描述】:

我想修改while 循环中的vector 堆栈条目,但不知何故引用修改不起作用。我想我正在修改复制的一个,但我不知道如何修改真正的条目。

#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>

int main() {
  struct Node {
    Node* parent;
    std::vector<std::unique_ptr<Node> > children;

    Node(Node* parent) : parent(parent){};
  };

  struct Tree {
    std::unique_ptr<Node> root;

    Tree():root(new Node{nullptr}){};
  };



  std::unique_ptr<Tree> t{new Tree};

  auto p = t->root.get();

  p->children.emplace_back(new Node{p});
  p->children.emplace_back(new Node{p});

  p = p->children[0].get();
  p->children.emplace_back(new Node{p});

  p = p->children[0].get();
  p->children.emplace_back(new Node{p});
  p->children.emplace_back(new Node{p});



  using Сhildren_const_iterator = decltype(std::cbegin(t->root->children));

  struct FirstCurrentLast {
    const Сhildren_const_iterator first;
    Сhildren_const_iterator current;
    const Сhildren_const_iterator last;
  };

  std::vector<FirstCurrentLast> stack;

  stack.push_back({std::cbegin(t->root->children),
                   std::cbegin(t->root->children),
                   std::cend(t->root->children)});





  auto print_stack = [&stack]() {
    std::cout << "/stack.size= " << stack.size() << "\n";

    std::string row1, row2, row3;
    for (auto&& it : stack) {
      row1.append(std::to_string(0)).append("_.");
      row2.append(std::to_string(it.current - it.first)).append("_.");
      row3.append(std::to_string(it.last - it.first)).append("_.");
    };

    std::cout << "first  |" << row1 << ";\n";
    std::cout << "current|" << row2 << ";\n";
    std::cout << "last   |" << row3 << ";\n\n";
  };





  while (!stack.empty()) {
    FirstCurrentLast& iterators = stack.back();
    Сhildren_const_iterator first = iterators.first;
    Сhildren_const_iterator& current = iterators.current;
    Сhildren_const_iterator last = iterators.last;

    std::cout << ">begin \n";

    print_stack();

    if (current == last) {
      stack.pop_back();
      continue;
    };

    if (!current->get()->children.empty()) {
      print_stack();

      stack.push_back({std::cbegin(current->get()->children),
                       std::cbegin(current->get()->children),
                       std::cend(current->get()->children)});

      print_stack();
    };

    iterators.current++;


    print_stack();

    std::cout << "end<\n\n";
    abort();
  };

  std::cout << "fini ok\n";
}

我得到输出:

>begin
/stack.size= 1
first  |0_.;
current|0_.;
last   |2_.;

/stack.size= 1
first  |0_.;
current|0_.;
last   |2_.;

/stack.size= 2
first  |0_.0_.;
current|0_.0_.;
last   |2_.1_.;

/stack.size= 2
first  |0_.0_.;
current|0_.0_.;
last   |2_.1_.;

end<

但它应该是这样的:

>begin
/stack.size= 1
first  |0_.;
current|0_.;
last   |2_.;

/stack.size= 1
first  |0_.;
current|0_.;
last   |2_.;

/stack.size= 2
first  |0_.0_.;
current|1_.0_.;
last   |2_.1_.;

/stack.size= 2
first  |0_.0_.;
current|1_.0_.;
last   |2_.1_.;

end<

【问题讨论】:

  • 你到底在哪里改变元素的值?
  • @NutCracker - iterators.current++;

标签: c++


【解决方案1】:

问题可能是因为您的iterators 引用在stack 向量上被push_back 无效。尝试使用deque 而不是vector 或在调用push_back 后重新获取对所需向量元素的引用。

【讨论】:

  • 很好,但不清楚您所说的“重新获取参考”是什么意思
  • 通常,这意味着在push_back之后,通过使用元素的索引再次获取引用。
  • 我知道了,但仍然不清楚如何在 C++ 中重新绑定引用。据我所知,在创建引用后匹配不能改变它所指的内容。你能解释一下你建议的机制吗?
  • 您不能重新绑定引用,但可以销毁旧引用(通过将其包含在{} 范围内)并使用索引创建新引用。
  • 我明白了,感谢您的澄清。在这种特殊情况下auto oldcurrent = iterators.current++; 在添加之前我会简单得多,但无论如何,这段代码需要重新编写恕我直言,在这种状态下它太不可读了。
猜你喜欢
  • 2013-02-13
  • 2018-02-17
  • 1970-01-01
  • 1970-01-01
  • 2015-05-14
  • 1970-01-01
  • 2017-03-23
  • 2021-04-23
  • 2021-04-21
相关资源
最近更新 更多