首页 > 解决方案 > 通过引用返回迭代器

问题描述

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

#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& x: *tree). 我如何给它一个参考?创建迭代器时是否有这样做的标准方法?当我返回数据值时,我将它分配给迭代器数据成员,以便我可以通过引用返回。我必须对我的迭代器做同样的事情吗?我不认为这是这样做的标准方式。

标签: c++classiteratorcontainers

解决方案


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

我如何给它一个参考?

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

创建迭代器时是否有这样做的标准方法?

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

我不认为这是这样做的标准方式。

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


我想在其中使用它的 for-range 循环看起来像for(auto& x: *tree)

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

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

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


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


推荐阅读