【问题标题】:returning a iterator by reference通过引用返回迭代器
【发布时间】:2021-05-09 08:39:45
【问题描述】:

我想通过引用访问我的迭代器类

#include <iostream>

template <typename T> class binary_tree;

template <typename T> 
class binary_tree_iterator {
private:
    binary_tree<T>* tree;
    T data;

public:
    binary_tree_iterator(binary_tree<T>* t) : tree(t) {}
    T& operator*() {data = tree->data(); return data;}
    binary_tree_iterator& operator++() {tree = tree->get_node(); return *this;}
    bool operator!=(binary_tree_iterator& rhs) {return tree->data() != rhs.tree->data();}     
};

template <typename T> 
class binary_tree {       
private:
    T t_data;
    binary_tree<T>* node;
    binary_tree_iterator<T>* It;

public:
    binary_tree(T d) : t_data(d), node(nullptr), It(nullptr)
    {}

    T& data() {
        return t_data;
    }
    
    void set_node(binary_tree<T>* node) {
        this->node = node;
    }
    
    binary_tree<T>* get_node() {
        return node;
    }

    binary_tree_iterator<T> begin() {     
        It = new binary_tree_iterator<T>(this);
        return *It;
    }
    
    binary_tree_iterator<T> end() {
        if(node == nullptr) {
            It = new binary_tree_iterator<T>(this);
            return *It;
        } else {
            return node->end();
        }
    }
};

int main() {
    binary_tree<int>* tree = new binary_tree<int>(2);
    tree->set_node(new binary_tree<int>(3));
    //for(auto& x: *tree) <--- does not work
    for(auto x: *tree) {
        std::cout << x << std::endl;
    }
}

我想在其中使用它的 for-range 循环类似于 for(auto&amp; x: *tree)。我如何给它一个参考?创建迭代器时是否有这样做的标准方法?当我返回数据值时,我将它分配给迭代器数据成员,以便我可以通过引用返回。我必须对我的迭代器做同样的事情吗?我不认为这是执行此操作的标准方式。

【问题讨论】:

  • for(auto&amp; x: *tree) x 中是对binary_tree 中当前数据节点的引用,而不是迭代器。有关基于范围的 for 循环扩展的伪代码,请参见此处 en.cppreference.com/w/cpp/language/range-for
  • 迭代器是轻量级和可复制的。 很少您应该持有对迭代器的引用。顺便说一句,你的树的 beginend 迭代器是相同的,所以在迭代循环期间,你的 binary_tree_iterator::operator++ 怎么知道它何时到达树的末尾?
  • @Remy 怎么样?
  • @Joemoor94 怎么样?请更具体。

标签: c++ class iterator containers


【解决方案1】:

我想通过引用访问我的迭代器类

我如何给它一个参考?

通过将函数的返回类型更改为binary_tree_iterator&lt;T&gt;&amp; 而不是binary_tree_iterator&lt;T&gt;。如果你这样做,你必须在某处存储一个迭代器而不是返回一个新的,以便你可以引用它。据推测,它必须作为成员变量存储。

在创建迭代器时有标准的方法吗?

没有。没有一个标准容器返回对迭代器的引用。

我不认为这是执行此操作的标准方式。

的确如此。 “标准”即常规做法是返回对迭代器的引用。


我想使用的 for-range 循环类似于 for(auto&amp; x: *tree)

无需返回对迭代器的引用即可使其工作。如果您查看标准容器,您会发现它们都没有返回对迭代器的引用,并且这样的循环适用于所有容器。

该循环中的引用通过迭代器绑定到间接结果。因此,operator* 必须返回对指向对象的引用。而且,您的 operator* 确实返回了一个参考。也就是说,通常迭代器会返回对存储在容器中的对象的引用。不是对存储在迭代器中的副本的引用。所以,这是非常规的。

写完你的迭代器,你会发现循环是有效的。


结论:您不需要通过引用返回迭代器,也不应该这样做。

【讨论】:

  • 似乎还是有问题
猜你喜欢
  • 1970-01-01
  • 2014-08-25
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 2017-03-20
相关资源
最近更新 更多