Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
116 views
in Technique[技术] by (71.8m points)

c++ - returning a iterator by reference

I want to access my iterator class by reference

#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;
    }
}

The for-range loop I want to use it in looks something like for(auto& x: *tree). How do I give it a reference? Is there a standard way of doing this when creating iterators? When I return the data value I assign it to a iterator data member so I can return by reference. Will I have to do the same with my iterator? I don't imagine this is the standard way of doing this.

question from:https://stackoverflow.com/questions/66055917/returning-a-iterator-by-reference

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I want to access my iterator class by reference

How do I give it a reference?

By changing the return type of the function to be binary_tree_iterator<T>& instead of binary_tree_iterator<T>. If you do that, you'd have to store an iterator somewhere instead of returning a new one, so that you can refer to it. Presumably, it would have to be stored as a member variable.

Is there a standard way of doing this when creating iterators?

No. None of the standard containers return references to iterators.

I don't imagine this is the standard way of doing this.

Indeed. The "standard" i.e. conventional thing to do is to not return references to iterators.


The for-range loop I want to use it in looks something like for(auto& x: *tree)

There is no need to return a reference to an iterator in order to make that work. If you take a look at standard containers, you'll find that none of them return a reference to an iterator, and such loop works with all of them.

The reference in that loop is bound to the result of indirection through the iterator. So, it is the operator* that must return a reference to the pointed object. And, your operator* does indeed return a reference. That said, normally an iterator would return a reference to the object stored in the container; not a reference to copy stored in the iterator. So, that's highly unconventional.

Finish writing your iterator, and you'll find that the loop works.


In conclusion: You don't need to return iterator by reference, and you shouldn't.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...