【问题标题】:Past-the-last element for non default-constructible elements非默认可构造元素的最后一个元素
【发布时间】:2017-10-10 16:18:48
【问题描述】:

在使用类 STL 接口的树类上工作时,我遇到了使用不可默认构造元素的问题:

在实现迭代器时,我需要在任何时间点都有一个过去最后一个元素。我的方法是在构造函数中创建一个,它断言值类型是默认可构造的。

有没有办法摆脱这个限制?

【问题讨论】:

  • 新的安置可以避免你过早的建设......只是说
  • 过去的结束元素不应该存在。
  • 当你说过去的最后一个元素时,也许你的意思是一个end 元素,对于原始数组来说,它可能是一个指向最后一个元素的指针,但不是必须的。您可以使用一些哨兵类型来表示“结束”。
  • 没有过去的元素是我的第一个方法。就基于指针的树而言,这自然是一个 nullptr。问题发生在我尝试实现双向迭代器的那一刻。我应该如何从过去的最后一个迭代器中找到最后一个元素?
  • 一些STL实现采用的解决方案是有一个不包含任何元素的过去最后一个节点。 Tbis 需要有两种节点类型,通常来自一个共同的基础。

标签: c++ stl iterator


【解决方案1】:

如果您的迭代器是双向的,则指向末尾不可能是 nullptrend()-- 必须是合法的。

它可以由哨兵实现,在这种情况下,哨兵甚至不应该包含默认构造的元素。

这样就可以了

struct link
{
    link *parent, *left, *right;
};

template<typename T>
struct node : link
{
    T data;
};

template<typename T>
struct tree : link
{
    // tree itself serves as the sentinel
    // At initialization parent and childs should all point to the sentinel
    tree() : parent(this), left(this), right(this) {}

    // ...
};

并且迭代器不需要对结束情况进行特殊处理。

// nested within tree
struct iterator
{
    explicit iterator(link* l) : n(l) {}
    iterator& operator--() { n = n->parent; return *this; }  // or something else
    auto& operator*() { return reinterpret_cast<node<T>*>(n)->data; }

    // ...

    link* n;
};
iterator begin() { return {left}; } // or something else
iterator end() { return {this}; }

【讨论】:

  • 您完全可以将迭代器类型设为nullptr。您只需要在operator--() 中添加一个检查。可以说这比将节点类型泄漏到客户端代码中要好。
  • @nwp 节点类型没有泄露,查看tree的接口。你如何从nullptr 倒退?假设你有两棵树,你怎么知道你指的是哪个end()?注意迭代器只有一个指针,没有另一个指向树本身
  • 这是我一直在寻找的通用解决方案,@PasserBy!
  • 无论如何,您都不能将原始指针用于树。你需要像struct Iterator { Node *node; }; 这样的东西才能完全实现operator--() 并且Iterator{nullptr}; 作为过去的迭代器值工作得很好。据我所见,tree publicly 继承自 linklink 也可以访问,但它不应该访问。
  • @nwp link 当然应该隐藏在一些实现命名空间中,为什么我需要的不仅仅是一个原始指针? Here 是使用上述相同想法的双向链表的玩具实现。由于我很懒,没有const_iterator,所以有点问题
【解决方案2】:

我通过存储另一个指向根节点的指针解决了这个问题,我可以在恒定时间内重新创建最后一个元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-02
    • 2016-04-21
    • 1970-01-01
    • 2021-05-15
    • 2017-11-28
    • 2014-06-19
    • 2012-04-02
    • 2013-04-29
    相关资源
    最近更新 更多